我注意到以下情况之间存在一些有趣的区别,但无法解释:
//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
所以基本上在第一种情况下返回相同的类型,在第二种情况下,返回Annotation类型。
有人可以解释这种行为吗?
答案 0 :(得分:8)
mehod getAnnotation
的签名如下:
public <A extends Annotation> A getAnnotation(Class<A> annotationClass)
现在两个调用之间的区别在于,您在第二个代码中使用Class
的原始类型myClass
。当您将原始类型用于泛型类型时,将擦除所有泛型类型信息,并且编译器将仅查看该特定引用的方法getAnnotation
的擦除,即:
public Annotation getAnnotation(Class annotationClass)
因此,它返回Annotation
,而不是MyAnnotation
。来自JLS §4.6 - Type Erasure:
类型变量(第4.4节)的擦除是其最左边界的擦除。
然而,在使用Class<?>
的情况下,类型参数A
将从您传递给方法的参数 - MyAnnotation
推断为Class<MyAnnotation>
。因此,返回类型的方法被视为MyAnnotation
。
构造函数的类型(第8.8节),实例方法(第8.4节,第9.4节),或者 原始类型
M
的非静态字段(第8.3节)C
,它不是从 它的超类或超接口是对应的原始类型 在相应的通用声明中擦除其类型C
。