4.2.18 ジェネリクスの使用に関する注意
ジェネリクスは,J2SE 5.0以降で使用できる機能です。ジェネリクスを使用すると,さまざまな型のオブジェクトを型やメソッドで使用する場合に,コンパイル時に型の安全性を保証できます。また,ジェネリクスを使用することで,データの型に依存しない,型そのものをパラメタとして扱うプログラミングを実現できます。
型を変数化することを型変数といいます。型変数は,ジェネリクスを使用したクラス,インタフェース,メソッドまたはコンストラクタの宣言時に使用します。「List<E> extends Collection<E>」という定義の場合,<E>の部分が型変数に該当します。
また,ジェネリクスを使用したクラス,インタフェース,メソッド,またはコンストラクタに対して,具体的なパラメタの型を指定することをパラメタ化といいます。例えば,「List<String>」,「Collection<Integer>」などが,パラメタ化されたクラスです。
- 〈この項の構成〉
(1) 型変数を使用できるインタフェース
インタフェースでは,メソッドの引数,戻り値,および例外で型変数を使用できます。使用する型変数は,インタフェース定義で宣言します。
(a) 型変数を使用できるインタフェースの種類
型変数を使用できるインタフェースの種類をEnterprise Beanの種別ごとに次の表に示します。
インタフェースの種類 |
Enterprise Beanの種別 |
||
---|---|---|---|
Session Bean |
Entity Bean |
Message-driven Bean |
|
ビジネスインタフェース |
△ |
− |
− |
Homeインタフェース |
× |
× |
− |
Componentインタフェース |
× |
× |
− |
メッセージリスナインタフェース |
− |
− |
○ |
その他(任意のインタフェース) |
○ |
○ |
○ |
(b) ビジネスインタフェースで型変数を使用した場合の注意事項
インタフェースで定義した型変数をビジネスインタフェースでパラメタ化した際に,パラメタ化したビジネスインタフェースのメソッドを再定義した場合,型変数を使用した個所とインタフェース種別の組み合わせによって,エラーになることがあります。エラーが発生した場合は,再定義したメソッドを削除して対処してください。
ビジネスインタフェースでメソッドを再定義した場合にエラーとなる組み合わせを次の表に示します。
型変数を使用した個所 |
ローカルインタフェース |
リモートインタフェース |
---|---|---|
戻り値 |
○ |
○ |
引数 |
× |
× |
例外 |
○ |
○ |
エラーが発生するのは,次の項目の両方に該当する場合です。
-
インタフェースで定義した型変数をパラメタ化している。
-
型変数をパラメタ化したインタフェースを継承したインタフェース内で,メソッドを再定義している。
エラーが発生するコーディングの例を次に示します。この例の場合,エラーを回避するためには,MyInterfaceの定義からメソッド「String get(Float args)」の定義を削除する必要があります。
public interface SuperInterface<T> { String get(T args); } // SuperInterfaceをパラメタ化して継承したメソッドを再定義している。 public interface MyInterface extends SuperInterface<Float> { // エラー回避のためには,次の再定義したメソッド定義を削除する必要がある。 String get(Float args); }
(2) 型変数を使用できるクラス
クラスでは,メソッドのシグネチャおよびメソッド内で型変数を使用できます。
型変数を使用できるクラスの種類をEnterprise Beanの種別ごとに次の表に示します。
クラスの種類 |
Enterprise Beanの種別 |
||
---|---|---|---|
Session Bean |
Entity Bean |
Message-driven Bean |
|
Enterprise Beanクラス |
○ |
○ |
○ |
インターセプタクラス |
○ |
− |
− |
その他(任意のクラス) |
○ |
○ |
○ |
(3) その他
ジェネリックメソッドやジェネリックコンストラクタにアプリケーションサーバが対応するアノテーション※は指定できません。指定した場合は無視されます。
ジェネリックメソッド,ジェネリックコンストラクタの例を次に示します。
注※ アプリケーションサーバが対応するアノテーションについての詳細は,マニュアル「アプリケーションサーバ リファレンス API編」の「2.1 アノテーションのサポート範囲」を参照してください。
class MyClass{ // ジェネリックコンストラクタ <T1> MyClass(Collection<T1> c){}; // ジェネリックメソッド <T2> void MyMethod(Collection<T2> c){}; }