类与类<?>实例中的getAnnotation()

And*_*i I 2 java generics

我注意到以下情况之间存在一些有趣的区别,但无法解释:

//this works
Class<?> myClass = Class.class;
MyAnnotation myAnnotation = myClass.getAnnotation(MyAnnotation.class);

//this does not work
Class myClass = Class.class;//note this is not generic anymore
MyAnnotation myAnnotation = myClass.getAnnotation(MyAnnotation.class);//it says: Type mismatch: cannot convert from Annotation to MyAnnotation
Run Code Online (Sandbox Code Playgroud)

所以基本上在第一种情况下返回相同的类型,在第二种情况下,返回Annotation类型.

有人可以解释这种行为吗?

Roh*_*ain 8

mehod的签名getAnnotation看起来像这样:

public <A extends Annotation> A getAnnotation(Class<A> annotationClass)
Run Code Online (Sandbox Code Playgroud)

现在2个调用之间的差异,使用的是原始类型ClassmyClass在第二个代码.当您使用原始类型作为泛型类型时,将擦除所有泛型类型信息,并且编译器将仅getAnnotation查看该特定引用的方法的擦除,即:

public Annotation getAnnotation(Class annotationClass)
Run Code Online (Sandbox Code Playgroud)

所以,它返回Annotation,而不是MyAnnotation.来自JLS§4.6 - 类型擦除:

类型变量(第4.4节)的擦除是其最左边界的擦除.

然而,在使用的情况下Class<?>,类型参数A将从MyAnnotation您传递给方法的参数推断出来Class<MyAnnotation>.因此,返回类型的方法被视为MyAnnotation.

JLS§4.8 - 原始类型:

未从其超类或超接口继承M的原始类型的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)的类型C是与之对应的原始类型.在对应的通用声明中擦除其类型 C.