Javaのジェネリクスはコンパイル時に解決され、classファイルになった時にはジェネリクスの型情報は残されていません。そのためイレイジャ(型消去:type erasure)方式と呼ばれます。
と、ひとくちで言っても意味がよく分からないのでちょっと掘り下げてみましょう。
インスタンスからジェネリクスの型情報は拾えない
リフレクションを用いたとしても、インスタンスからジェネリクス型パラメータが何であるかを取得することはできません。
List<String> stringList = new ArrayList<String>();
のような変数stringListがあったとして、ここから<String>を取得するということができないのです。これが消えてしまった部分。
この変数stringListに対する各種操作において、その型の安全はコンパイル時に精査され、
実行時にはあくまでObject型引数のメソッドを通したやりとりで動くのです。
クラス宣言に関わるジェネリクス型情報は拾える
しかし、型の宣言に関する部分はリフレクションで拾うことができます。ここが混乱する部分ですね。
- 親クラスを継承する際に投入しているジェネリクス型パラメータ
- インターフェースを実装する際に投入しているジェネリクス型パラメータ
- メソッドの引数・戻り値に用いられているジェネリックな型とそこに渡される型パラメータ
- フィールドに用いられているジェネリックな型とそこに渡される型パラメータ
といった情報は拾えるわけです。
public class Piyo
extends Hoge<String>
implements IHoge<String> {
private List<String> value;
public List<String> get() {
return this.value;
}
public void set(List<String> value) {
this.value = value;
}
}
といったコードがあった場合、リフレクションで親クラスがHoge<String>型であることを拾えます。インターフェースも同等。
また、フィールドやメソッドの戻り値・引数がList<String>型であることも拾うことができます。
投稿日時 : 2008年10月13日 20:21