appendix> util> generics | TOPUPPREVNEXT |
1.4 以前では、コレクションに 要素を add し、 get すると常に Object クラスの要素が返され、 通常はキャストをして使わなければなりませんでした。 ジェネリックを使うと、 「String」の ArrayList とか、「Number クラスを継承するクラス達」の SortedSet といったものを 取り扱えるようになります。
ジェネリックスはコンパイラの機能であり、コンパイル時に型検査がされ、 Object クラスを処理するコードを生成し、 キャストを行うコードが挿入されます。 実行時の型検査が行われるわけではありません。
たとえば、 Collection<String> 、Collection<JLabel> 、あるいは List<Integer> といった形で参照されます。 参照されるとたとえば、String だけからなる Collection 、 JLabel だけからなる Collection 、Integer の List などのように要素の型が限定されたコレクションを表します。 一旦 E に String を割り当てたら、その定義についての E は全て String で置き換えて読みます。 もし <T> のように異なった変数が現れた場合には、別のクラスを対応付けることができます。
対応付けができるのはクラスの名前です。 int とか double といった基本データ型を指定してはいけません。
型変数の宣言を書ける場所は以下の3つです。
変数には任意の識別子を用いることができますが、通常つぎのような名前を使う習慣になっています。
複数の変数を宣言する場合は、コンマで区切ってならべます。
インターフェースの例 StackInterface.java
クラス定義の例 Stack.java
クラス参照の例 StackDemo1.java
実行例
StackDemo1.java の 8〜9行目は int 型が Integer 型に自動的に型変換され、 20〜21行目では、int 型や double 型から Integer型や Double型に自動的に型変換されています。 これは J2SE 5.0 で提供された ボクシング という機能です。
20〜22行目の ns.push のパラメータは Number クラスが要求されていますが、 Integer 型 や Double 型は Munber型 を継承していますからそのまま渡せます。 26〜28行目は、ns.pop の型は Number ですので、 54〜57行目に書かれている convert が呼ばれます。
6行目は、型を限定しないクラス参照です。 31〜34行目のように様々なクラスを渡せますが、無検査のむね警告が表示されます。 コンパイルのオプションに −Xlint:unchecked を指定すると、 上図のように警告が表示されます。このオプションを指定しない場合は、 警告がある旨のメッセージが1行表示されます。 38〜41行目の xs.pop は Object 型とみなされ、58〜80行目の convert が呼ばれます。 ここでは、返された値をしかるべき型にキャストをしてから使います。 Integer 型と Double 型は Menber 型を継承していますから、64〜71行目を削除すれば、 Menber 型として処理されます。
型変数の参照では継承関係は考慮されません。 <Object> とあれば、 Object クラスそのものを指します。