Luk*_*der 20 java annotations javac
我有这个示例设置:
p.E
package p;
public enum E { E }
Run Code Online (Sandbox Code Playgroud)
p.A
package p;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface A {
p.E e();
}
Run Code Online (Sandbox Code Playgroud)
q.Test
package q;
import p.*;
@A(e = E.E)
public class Test {
public static void main(String[] args) {
System.out.println("Test.main()");
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我现在可以这样做:
$ javac q/Test.java
$ rm p/*.class
$ ll */*
-rw-r--r-- 1 lukas 197609 118 Mar 28 10:21 p/A.java
-rw-r--r-- 1 lukas 197609 32 Mar 28 09:43 p/E.java
-rw-r--r-- 1 lukas 197609 486 Mar 28 10:22 q/Test.class
-rw-r--r-- 1 lukas 197609 153 Mar 28 09:55 q/Test.java
$ java q/Test
Test.main()
Run Code Online (Sandbox Code Playgroud)
没问题,注释是可选的并且被运行时忽略,没有NoClassDefFoundError
但是,当我也删除源文件时p,保留编译后的Test.class:
$ rm -Rf p
Run Code Online (Sandbox Code Playgroud)
然后创建:
x.Test2
$ rm -Rf p
Run Code Online (Sandbox Code Playgroud)
编译该类会发出警告:
package x;
public class Test2 {
q.Test test;
}
Run Code Online (Sandbox Code Playgroud)
对于不依赖于任何枚举的注释,我没有收到此警告。即重复这些过程,并且没有警告:
p.A
$ javac x/Test2.java
warning: unknown enum constant E.E
reason: class file for p.E not found
1 warning
Run Code Online (Sandbox Code Playgroud)
q.Test
package p;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface A {}
Run Code Online (Sandbox Code Playgroud)
当A引用Class<E>而不是E.E枚举值时,我仍然没有收到任何警告:
p.A
package q;
import p.*;
@A
public class Test {
public static void main(String[] args) {
System.out.println("Test.main()");
}
}
Run Code Online (Sandbox Code Playgroud)
q.Test
package p;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
public @interface A {
Class<?> a();
}
Run Code Online (Sandbox Code Playgroud)
enum,但我可能会遗漏一些东西。对于上下文:现实世界的用例是:
p来自 JAXBq包含引用注释的库代码的包是一个库,其依赖项是p可选的。(具体为 jOOQ,更多详细信息请参见此处)x包是客户端代码,具体取决于q包,它具有对 的可选依赖项p,这意味着默认情况下该依赖项实际上是缺失的。正如用户 yyyy以及库 bug tracker上的评论,当前行为是由修复JDK-6550655定义的,该修复在 Java 7 中引入了警告(之前,此注释/枚举的使用导致了编译错误)。
JDK-6550655略有不同。p.E该警告是针对仅缺少枚举而不缺少注释的情况引入的p.A,在这种情况下,p.A使用反射 API 访问时确实会出现不希望的运行时错误。警告开发人员这种情况当然是值得的。然而,在这种情况下,p包的所有内容都不存在,这意味着不会有任何运行时错误,并且根据注释的设计,不存在应该没问题,允许不存在。
在我看来,这是 javac 中的一个错误,我已经报告了:JDK-8305250。它可能会也可能不会被接受或修复。
| 归档时间: |
|
| 查看次数: |
3037 次 |
| 最近记录: |