Java 5中注解类型的编译时检查是如何改变的?

How is the compile time check of the type of annotations changed in Java 5?

我正在查看 Java 5 中引入的更改,以下文档对我来说似乎不清楚。

<T extends Annotation> T getAnnotation(Class<T> annotationType); 

This is a generic method. It infers the value of its type parameter T from its argument, and returns an appropriate instance of T, as illustrated by the following snippet:

    Author a = Othello.class.getAnnotation(Author.class);

Prior to generics, you would have had to cast the result to Author. Also you would have had no way to make the compiler check that the actual parameter represented a subclass of Annotation.

通过使用 Annotation 作为参数类型,我仍然能够让编译器检查该参数是否表示 Annotation 的子类。我在这里缺少什么,编译时检查如何随着泛型的引入而改变?

我同意我现在不需要转换结果。

"...代表子类..."不代表子类的实例。在那种情况下,您 可以 使用 Annotation 作为参数类型。相反,它表示 Class 的实例对应于 Annotation.

的子类

没有泛型:

Annotation getAnnotation(Class annotationType);

您可以将任何 Class 传递给该方法。例如:

SomeType.class.getAnnotation(Object.class);

虽然 Object 实际上不是 Annotation 的子类型。

但是对于泛型,你有一个类型绑定,Class 本身有一个泛型参数,它是它编码的类型。

对于泛型,传递具有 Class<Object> 类型的 Object.class 会引发编译器错误,因为 T 将是 Object,而 Object不符合界限:<T extends Annotation>.

What am I missing here, how is the compile time check changed with the introduction of generics?

第一件事。 Java 5 中也引入了注释。

但是让我们假设它们在那之前就存在了。 getAnnotation 的(假设的)pre-Java 5 版本的签名必须是:

 Annotation getAnnotation(Class annotationType); 

所以获取作者注解需要写成:

 Author a = (Author) Othello.class.getAnnotation(Author.class); 

getAnnotation 的类型签名只允许编译器知道 Annotation 是 returned。 In 不知道 Annotation 的特定子类型 (Author) 是 returned。因此显式类型转换1 是执行运行时检查所必需的。

现在,您还可以假设他们 可以 getAnnotation 做一个特例(因为这是一个系统 class)。但是,该示例是为了说明有关 normal Java 类型检查的一点。此外,在 Java 4 和更早版本中还有其他示例,他们本可以添加类似的特殊情况,但没有。 (谢天谢地!)


1 - 事实上,如果您检查一般情况下调用序列的生成字节码,您会发现编译器已为结果赋值插入隐式类型转换。这是必要的,因为泛型方法可能使用未经检查的转换和 return 违反连接参数和结果类型的类型约束的对象。