Javaプラットフォームの3つのエディション
Javaは用途に応じて3つのエディションに分かれています。
- Java SE (Standard Edition): 標準版。デスクトップアプリケーションやサーバー向けのコア機能を提供します。
- Java ME (Micro Edition): 小型デバイスや組み込み向け。現在はAndroidなどにその役割を譲っています。
- Java EE (Enterprise Edition): 企業向け。大規模なネットワークシステムやサーバーサイド開発(Jakarta EE)に使用されます。
JDK 1.5以前は「J2SE」のように呼ばれていましたが、以降は現在の名称に変更されました。Javaの生みの親はジェームズ・ゴスリン氏です。
Java言語の主な特徴と動作原理
Javaの最大の特徴は「マルチプラットフォーム(プラットフォーム独立性)」です。ソースコードをコンパイルすると、OSに依存しないバイトコードが生成されます。これを各OS用のJVM(Java仮想マシン)が実行することで、一度書けばどこでも動く(Write Once, Run Anywhere)仕組みを実現しています。
JDKの構成と環境構築
開発を行うにはJDK(Java Development Kit)が必要です。
- JDK: 開発ツール(javacなど)とJREのセット。
- JRE: Javaプログラムを実行するための環境(JVM + 実行用ライブラリ)。
- JAVA_HOMEの設定: 環境変数としてJDKのインストールディレクトリを指定し、Pathに
%JAVA_HOME%\binを追加することで、コマンドプロンプト等からJavaコマンドを直接呼び出せるようになります。
制御構文:switch文と三項演算子
条件分岐には三項演算子(条件 ? 真の式 : 偽の式)や、固定値の判定に適したswitch文が使われます。switch文では、JDK 1.5から列挙型、JDK 1.7からString型がサポートされました。breakを忘れると「フォールスルー(caseの突き抜け)」が発生するため注意が必要です。
メソッドのオーバーロードとオーバーライド
- オーバーロード: 同一クラス内で、名前が同じで引数の構成が異なるメソッドを定義すること。
- オーバーライド: 親クラスのメソッドを子クラスで再定義すること。シグネチャが一致している必要があります。
変数とメモリ管理
Javaの変数は定義場所によって性質が異なります。
- メンバ変数: クラス内で定義され、ヒープ領域に保持されます。インスタンス生成時にデフォルト値(0やnull)で初期化されます。
- ローカル変数: メソッド内で定義され、スタック領域に保持されます。使用前に必ず明示的な初期化が必要です。
Propertiesクラスによる設定管理
Propertiesクラスは、キーと値が共にString型のマップ構造を持ち、設定ファイルの読み書きに特化しています。
Properties settings = new Properties();
// 読み込み
try (FileInputStream in = new FileInputStream("app.config")) {
settings.load(in);
}
// データの更新と保存
settings.setProperty("theme", "dark");
try (FileOutputStream out = new FileOutputStream("app.config")) {
settings.store(out, "System Settings");
}
オブジェクトのシリアル化(Serialization)
メモリ上のインスタンスをバイトストリームとして出力したり、逆に復元したりすることをシリアル化・逆シリアル化と呼びます。
// 読み込み(逆シリアル化)
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))) {
User user = (User) ois.readObject();
System.out.println(user.getName());
} catch (Exception e) {
e.printStackTrace();
}
ByteArrayOutputStreamによるメモリバッファ操作
ファイルではなくメモリ上のバッファへデータを書き込み、一括で取得する際に利用します。リソースのクローズは必須ではありません。
FileInputStream input = new FileInputStream("data.txt");
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] chunk = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(chunk)) != -1) {
buffer.write(chunk, 0, bytesRead);
}
System.out.println(buffer.toString("UTF-8"));
input.close();
コレクションフレームワーク:ArrayListとHashSet
- ArrayList: 順序を保持し、重複を許可します。
- HashSet: 順序を保持せず、重複を許可しません。
リストから重複を除去する簡便な方法として、一度Setに変換する手法がよく使われます。
List<String> items = new ArrayList<>(Arrays.asList("A", "B", "A", "C"));
Set<String> uniqueItems = new HashSet<>(items);
items.clear();
items.addAll(uniqueItems);
instanceof演算子と型の判定
ポリモーフィズムを利用する際、実際のインスタンス型を確認するために使用します。
public void processAnimal(Animal animal) {
animal.makeSound();
if (animal instanceof Dog) {
((Dog) animal).fetchBall();
} else if (animal instanceof Cat) {
((Cat) animal).scratchPost();
}
}
ConcurrentModificationExceptionとその回避策
Iterator等でコレクションをループしている最中に、コレクションの要素を直接追加・削除しようとするとこの例外が発生します。回避するにはIteratorのremove()メソッドを使うか、CopyOnWriteArrayListのようなスレッドセーフなコレクションを使用します。
Collectionsユーティリティ
Collectionsクラスは、リストの操作に便利な静的メソッドを提供します。
sort(list): 昇順ソートreverse(list): 要素の反転shuffle(list): シャッフル(ランダム化)max(list) / min(list): 最大値・最小値の取得