joh*_*dav 4 java reflection language-lawyer
Javadocs条目getDeclaredAnnotations说明如下:
返回直接出现在该元素上的注释。此方法忽略继承的注释。如果此元素上没有直接存在注释,则返回值是长度为 0 的数组。此方法的调用者可以自由修改返回的数组;它不会影响返回给其他调用者的数组。
所以,我希望这个函数在 上返回一个长度为 1 的数组doSometing,然而,它返回一个长度为 0 的数组。为什么?getAnnotation对于相关类型也返回null.
MCVE:
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class AnnotationTest{
public static void main(String[] args){
Class<?> clazz = AnnotationTest.class;
for(Method method : clazz.getMethods()){
System.out.println(method.getName() + ":");
for(Annotation annotation : method.getDeclaredAnnotations()){
System.out.println(" - " + annotation.annotationType().getName());
}
System.out.println();
}
}
@ExampleAnnotation
public void doSomething(){}
public @interface ExampleAnnotation{}
}
Run Code Online (Sandbox Code Playgroud)
实际 MCVE 输出:
main:
doSomething:
wait:
wait:
wait:
equals:
toString:
hashCode:
- jdk.internal.HotSpotIntrinsicCandidate
getClass:
- jdk.internal.HotSpotIntrinsicCandidate
notify:
- jdk.internal.HotSpotIntrinsicCandidate
notifyAll:
- jdk.internal.HotSpotIntrinsicCandidate
Run Code Online (Sandbox Code Playgroud)
预期 MCVE 输出:
// irrelevant method entries aren't shown
doSomething:
- AnnotationTest.ExampleAnnotation
// irrelevant method entries aren't shown
Run Code Online (Sandbox Code Playgroud)
根据 Java 语言规范\xc2\xa79.6.4.2,
\n\n\n如果
\nT没有m对应于 的(元)注释java.lang.annotation.Retention,那么 Java 编译器必须将T其视为确实具有m值为 的元素的元注释java.lang.annotation.RetentionPolicy.CLASS。
您ExampleAnnotation没有@Retention元注释,因此它仅保留在类文件中。但是,它必须在运行时保留,以便通过反射进行访问。来自以下文档RetentionPolicy.RUNTIME:
\n\n注解将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取它们。
\n
将其与 的描述进行比较CLASS:
\n\n注释将由编译器记录在类文件中,但 VM 在运行时不需要保留。
\n
ExampleAnnotation因此,为了获得所需的输出,您应该这样声明:
@Retention(RetentionPolicy.RUNTIME)\n@interface ExampleAnnotation{}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
684 次 |
| 最近记录: |