首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么缺失的注解不会在运行时导致ClassNotFoundException?

为什么缺失的注解不会在运行时导致ClassNotFoundException?
EN

Stack Overflow用户
提问于 2010-08-25 23:14:51
回答 2查看 13.8K关注 0票数 97

考虑以下代码:

A.java:

代码语言:javascript
复制
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

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

C.java:

代码语言:javascript
复制
import java.util.*;

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

编译和运行工作符合预期:

代码语言:javascript
复制
$ javac *.java
$ java -cp . C
[@A()]

但请考虑以下内容:

代码语言:javascript
复制
$ rm A.class
$ java -cp . C
[]

我本以为它会抛出一个ClassNotFoundException,因为缺少@A。但是,它会默默地删除注释。

这种行为是否记录在JLS中的某个地方,或者它是Sun的JVM的怪癖?这样做的理由是什么?

对于像javax.annotation.Nonnull这样的东西,它似乎很方便(它看起来无论如何都应该是@Retention(CLASS) ),但对于许多其他注释,它似乎会在运行时导致各种不好的事情发生。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-26 00:19:33

在JSR-175的早期公开草案(注释)中,讨论了编译器和运行时是否应该忽略未知注释,以便在注释的使用和声明之间提供更松散的耦合。一个特定的示例是在EJB上使用特定于应用程序服务器的注释来控制部署配置。如果相同的bean应该部署在不同的应用程序服务器上,如果运行时简单地忽略未知注释而不是引发NoClassDefFoundError,将会很方便。

即使用词有点含糊,我假设您看到的行为是在JLS 13.5.7中指定的:“……删除注释不会影响Java编程语言中程序的二进制表示的正确链接。”我的解释是,如果注释被移除(在运行时不可用),程序仍然应该链接和运行,这意味着当通过反射访问时,未知的注释只是被忽略。

SunJDK5的第一个版本没有正确地实现这一点,但在1.5.0_06中得到了修复。您可以在bug数据库中找到相关的bug 6322301,但是它并没有指向任何规范,只是声称“根据JSR-175规范的领导,未知的注释必须被getAnnotations忽略”。

票数 96
EN

Stack Overflow用户

发布于 2010-08-26 01:10:36

如果你实际有读取@A的代码,并对它做了一些事情,那么代码依赖于类A,并且它将抛出ClassNotFoundException。

如果不是,也就是说没有代码特别关心@A,那么可以说@A并不重要。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3567413

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档