Java 注释不可见?

Java 注释不可见?,java,reflection,annotations,Java,Reflection,Annotations,这让我困惑。我有一个带有自定义注释的类,我似乎无法验证注释是否存在。我做错了什么?如果我运行MyOperationTest(见下文),我会得到以下结果: implements Library.Operation: true has @Library.Marker: false Tada! Library.java: package com.example.gotchas; public class Library { private Library() {} public

这让我困惑。我有一个带有自定义注释的类,我似乎无法验证注释是否存在。我做错了什么?如果我运行
MyOperationTest
(见下文),我会得到以下结果:

implements Library.Operation: true
has @Library.Marker: false
Tada!

Library.java:

package com.example.gotchas;

public class Library {
    private Library() {}

    public @interface Marker {}

    public interface Operation {
        public void execute(); 
    }
}
MyOperation.java:

package com.example.gotchas;

@Library.Marker
public class MyOperation implements Library.Operation {
    @Override public void execute() {
        System.out.println("Tada!");
    }
}
MyOperationTest.java:

package com.example.gotchas;

public class MyOperationTest {
    static public void main(String[] args)
    {
        try {
            Class<?> cl = Class.forName("com.example.gotchas.MyOperation");
            boolean implementsLibraryOperation =
                Library.Operation.class.isAssignableFrom(cl);
            boolean hasLibraryMarker =
                cl.isAnnotationPresent(Library.Marker.class);
            System.out.println("implements Library.Operation: "
                    +implementsLibraryOperation);
            System.out.println("has @Library.Marker: "+hasLibraryMarker);
            if (implementsLibraryOperation)
            {
                Class<? extends Library.Operation> opClass = 
                    cl.asSubclass(Library.Operation.class); 
                Library.Operation op = opClass.newInstance();
                op.execute();
            }
        }
        catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        catch (InstantiationException e) {
            e.printStackTrace();
        }
        catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
package com.example.gotchas;
公开课考试{
静态公共void main(字符串[]args)
{
试一试{
Class cl=Class.forName(“com.example.gotchas.MyOperation”);
布尔运算=
Library.Operation.class.isAssignableFrom(cl);
布尔hasLibraryMarker=
cl.isAnnotationPresent(Library.Marker.class);
System.out.println(“实现库操作:”
+实施图书馆业务;
System.out.println(“has@Library.Marker:+hasLibraryMarker”);
if(实施图书馆操作)
{
类必须为注释定义:

@Retention(RetentionPolicy.RUNTIME)
public @interface Marker {}
否则,在运行时不会保留注释

(如果要限制注释仅在类上使用,还可以添加显式的
@Target(ElementType.TYPE)


作为旁注-将注释定义为内部类不是一种常见做法。

默认情况下,注释保留策略为
CLASS
,这不会使您的注释对反射可用。您应该在声明注释时对其进行限定。

同意。默认情况下,注释不会在运行时…在c之后保留ompile time已删除。因此,当您运行测试代码时,注释不再是已编译代码的一部分。更多详细信息,请参阅:运行时-注释将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射地读取它们。