Java Genericsの裏側を知る
翻訳校正:原井彰弘
Java 1.5で追加されたGenericsについて、その使い方と効果を解説する
Java 1.5の先進機能であるGenericsを用いると、型に関するチェックが行えるようになり、CollectionインタフェースやArrayListクラスが扱うオブジェクトを特定のオブジェクト型に限定することが可能になる。
また、Genericsを用いると、オブジェクトのソートの際に正しい種類のComparatorを用いているかどうかもチェックすることが可能になる。この型チェックは、ほぼすべてコンパイル時に行われる(C++にはテンプレートと呼ばれる類似の機能がある)。
Genericsの動作
Javaの場合、Collectionインタフェースを実装するクラス(たとえば、HashMapクラス、ArrayListクラス、TreeListクラス)すべてにおいて、コレクションに含まれる要素はジェネリックなObjectオブジェクトとして扱われる。ここで問題なのは、コレクション内にどのような種類のオブジェクトが保持されているのかは、自分で管理する必要があるということだ。たとえば、DogオブジェクトのコレクションにCatオブジェクトを追加したとしても、コンパイラは何も警告をしないのである。そこで、Java 1.5ではGenericsが導入された。
しかし、このGenericsは高いオーバーヘッドを伴う手法で実装されている。コレクションに要素を追加する際にも、コレクションから要素を取り出す際にも、暗黙的な型キャストが必要となるのだ。コンパイラは、コレクションに追加されるすべてのオブジェクトを(たとえば)Dog型に自動的にキャストし、それらが取り出されるときには再びDog型にキャストする作業を自動で行うのである。一方、コレクションの内部では、それらの要素は単にジェネリックなObject型として扱われる。理論上は、これらの時間が掛かるキャストは2回とも必要ないのだが、キャストを除去すると、それがセキュリティホールとなってJVMの脆弱性につながる危険性があるため、取り除くことはできない。
新しい構文とオートボクシング
JavaにおけるGenericsでは、クラスの型パラメータには正式にはオブジェクト型しか指定することができない。つまり、List<Integer>はコンパイル可能であるが、List<int>はコンパイルできないのである。しかしオートボクシング機能によって、プリミティブのint型をList<Integer>に追加することは可能となっている。オートボクシングとは、型を変換するコードを記述しなくてもプリミティブ型をオブジェクト型として扱える機能である。型変換に必要なコードは、コンパイラが自動的に補ってくれるのだ。それによって、J2SE 5.0以降では、たとえばint型を扱うLinkedListを作成することが可能になっている。本来、LinkedListはオブジェクト型のみを対象としており、プリミティブ型のリストは作成できない。しかし、オブジェクトを受け取るべき時にプリミティブ型が渡されると、そのプリミティブ型は直ちにオブジェクトに変換されるのである。
この動作はオートボクシングと呼ばれている。ボックス化は暗黙的かつ自動的に行われるので、手作業で行う必要がなくなるのである。また逆に、ボックス化されたプリミティブ型から、数学的な処理などのためにプリミティブ型を取り出すことは、非ボックス化と呼ばれる。以下に、Genericsとオートボクシング機能を用いたコードの例を挙げる。
int z = 5; List<Integer> digits = new Vector<Integer>(); Integer $int = (z * 32); // Boxing digits.add(++$int); // Unboxing $int = digits.get(0); // Boxing boolean is33 = $int == 33; // Unboxing
Genericsは型の正確さを保つためコンパイル時にチェックされる。このチェックが終了すると、ジェネリック型の情報は「型消去」(type erasure)と呼ばれる処理によって削除され、その後はスーパークラスのためだけに保持される。例を挙げると、List<Integer>は任意のオブジェクトを含むことが可能な非ジェネリック型のListに変換されるのである。チェックはコンパイル時に行われるため、コンパイラが未チェックの警告を発しない限り、最終的なコードは型として正しいことが保証されるのである。
- 昨日のトップ記事
- 2日前
- 3日前
- 4日前
- 5日前
- ホワイトペーパー
- 話題のタグ
キャリアコンサルタントのノウハウが最大の強みです
動画再生耐久レース―フル充電からどれだけ耐えた?
心当たりありませんか--あなたの上司がイヤがる5つの話し方
フォームデザイン虎の巻:複数の選択肢を提供する
フォトレポート:技術サポートの悪夢
無料の「Oracle Database XE」で高速バッチ処理:実装のポイント
Firefoxで情報をカンタン・ベンリに整理する
iPhone Safari、Acidテストでは高得点でも…… Firefoxは載らないの?:WebサイトのiPhone 3G対応問題を考える(ソフト編)
WebサイトのiPhone 3G対応問題を考える(ハード編)
フォトレポート:時代を振り返る--「MS-DOS 4」のインストール
SOAと仮想化の関係は?--常に進化を続けるBEAのミドルウェア戦略
ウェブ開発の生産性はどうしたら上がる?--MODIPHI Appsで半日で作るマッシュアップサイト(1)
JailBreakついに:PwnageTool公開
プロジェクトの進行でよくある4つのトラブル
ZDNet Japan Green IT
Techno Exchange
ZDNet Japan ホスティング特集
DELLが掲げる「新・仮想化アセスメントサービス」