ワイルドカード + 内部クラス + 無名クラス拡張 = ?
型パラメータつきのクラスに定義された内部クラスを、
型パラメータがワイルドカードの変数で参照されるインスタンスをエンクロージングインスタンスとして、
無名クラスで拡張すると、
Class.getGenericSuperClass() がGenericSignatureFormatErrorで落ちる。
package test; import java.lang.reflect.ParameterizedType; //型パラメータつきクラス class C<T> { // 内部クラス public class Inner {/**/} } public class InnerClassTypeTest { public static void main(final String[] args) { final C<String> c1 = new C<String>(); // C<String>.Inner ParameterizedType t1 = (ParameterizedType) c1.new Inner(){/**/} .getClass().getGenericSuperclass(); System.out.println(t1); // 変数の型引数をワイルドカードに、インスタンスは同じ C<?> c2 = c1; // C<?>.Inner と期待 ParameterizedType t2 = (ParameterizedType) c2.new Inner(){/**/} .getClass().getGenericSuperclass(); System.out.println(t2); } }
実行結果
test.C<java.lang.String>.Inner Exception in thread "main" java.lang.reflect.GenericSignatureFormatError at sun.reflect.generics.parser.SignatureParser.error(Unknown Source) at sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(Unknown Source) at sun.reflect.generics.parser.SignatureParser.parseFieldTypeSignature(Unknown Source) at sun.reflect.generics.parser.SignatureParser.parseTypeArgument(Unknown Source) at sun.reflect.generics.parser.SignatureParser.parseTypeArguments(Unknown Source) at sun.reflect.generics.parser.SignatureParser.parsePackageNameAndSimpleClassTypeSignature(Unknown Source) at sun.reflect.generics.parser.SignatureParser.parseClassTypeSignature(Unknown Source) at sun.reflect.generics.parser.SignatureParser.parseClassSignature(Unknown Source) at sun.reflect.generics.parser.SignatureParser.parseClassSig(Unknown Source) at sun.reflect.generics.repository.ClassRepository.parse(Unknown Source) at sun.reflect.generics.repository.ClassRepository.parse(Unknown Source) at sun.reflect.generics.repository.AbstractRepository.<init>(Unknown Source) at sun.reflect.generics.repository.GenericDeclRepository.<init>(Unknown Source) at sun.reflect.generics.repository.ClassRepository.<init>(Unknown Source) at sun.reflect.generics.repository.ClassRepository.make(Unknown Source) at java.lang.Class.getGenericInfo(Unknown Source) at java.lang.Class.getGenericSuperclass(Unknown Source) at test.InnerClassTypeTest.main(InnerClassTypeTest.java:24)
なお、無名クラスでなくclass宣言による拡張だと問題なさそうなので、ワイルドカードがダメというわけではないらしい。
package test; //型パラメータつき class C2<T> { // 内部クラス public class Inner {/**/} } // class宣言で拡張 class SubC2 extends C2<?>.Inner { // コンストラクタが必要 public SubC2() { new C2<String>().super(); } } public class InnerClassTypeTest2 { public static void main(final String[] args) { System.out.println(SubC2.class.getGenericSuperclass()); } }
実行結果
test.C2<?>.Inner