为什么不缺少注释导致在运行时一个ClassNotFoundException? [英] Why doesn't a missing annotation cause a ClassNotFoundException at runtime?

查看:155
本文介绍了为什么不缺少注释导致在运行时一个ClassNotFoundException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下code:

A.java:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
@interface A{}

C.java:

C.java:

import java.util.*;

@A public class C {
        public static void main(String[] args){
                System.out.println(Arrays.toString(C.class.getAnnotations()));
        }
}

编译和运行按预期工作:

Compiling and running works as expected:

$ javac *.java
$ java -cp . C
[@A()]

但后来考虑这个问题:

But then consider this:

$ rm A.class
$ java -cp . C
[]

我会一直期望它抛出一个的ClassNotFoundException ,因为 @A 缺失。但是,相反,它静静地丢弃注释。

I would've expected it to throw a ClassNotFoundException, since @A is missing. But instead, it silently drops the annotation.

这种行为是在JLS文件的某处,或者是Su​​n的JVM的怪癖?什么是理由吗?

Is this behaviour documented in the JLS somewhere, or is it a quirk of Sun's JVM? What's the rationale for it?

这似乎方便了像 javax.annotation.Nonnull 的东西(这似乎像它应该一直 @Retention(CLASS)反正),但对许多其他注释看起来它可能导致各种不好的东西在运行时发生的。

It seems convenient for things like javax.annotation.Nonnull (which seems like it should've been @Retention(CLASS) anyway), but for many other annotations it seems like it could cause various bad things to happen at runtime.

推荐答案

在早期的公共草稿JSR-175(注释),有人讨论,如果编译器和运行时应该忽略未知的注解,为客户提供之间的松耦合使用和标注的声明。一个具体的例子是在连接EJB来控制部署配置中使用的应用程序服务器的特定注释。如果同一个bean应该在不同的应用服务器上进行部署,这本来是方便,如果运行时简单地忽略未知的注释,而不是提高的NoClassDefFoundError的。

In the earlier public drafts for JSR-175 (annotations), it was discussed if the compiler and runtime should ignore unknown annotations, to provide a looser coupling between the usage and declaration of annotations. A specific example was the use of applications server specific annotations on en EJB to control the deployment configuration. If the same bean should be deployed on a different application server, it would have been convenient if the runtime simply ignored the unknown annotations instead of raising a NoClassDefFoundError.

即使用词有点含糊,我认为你所看到的行为JLS 13.5.7中指定的:......去掉注释对二重presentations正确的联动没有影响在Java编程语言编写的程序。我间preT这仿佛注释被删除(无法在运行时),该方案仍然应该链接并运行,而这意味着,通过反射访问时未知注释被忽略。

Even if the wording is a little bit vague, I assume that the behaviour you are seeing is specified in JLS 13.5.7: "... removing annotations has no effect on the correct linkage of the binary representations of programs in the Java programming language." I interpret this as if annotations are removed (not available at runtime), the program should still link and run and that this implies that the unknown annotations are simply ignored when accessed through reflection.

Sun的JDK 5的第一个版本没有正确地实现这一点,但它是固定在1.5.0_06。你可以找到相关的bug 在bug数据库6322301 ,但它并不指向任何规格声称除外说:根据JSR-175规范领导未知注释必须getAnnotations被忽略。

The first release of Sun's JDK 5 did not implement this correctly, but it was fixed in 1.5.0_06. You can find the relevant bug 6322301 in the bug database, but it does not point to any specifications except claiming that "according to the JSR-175 spec lead, unknown annotations must be ignored by getAnnotations".

这篇关于为什么不缺少注释导致在运行时一个ClassNotFoundException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆