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

时间:2014-02-06 11:08:03

标签: 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

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

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

1 个答案:

答案 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

请参阅JLS § 4.8 - Raw Types

  

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