注释不可见?

Jas*_*n S 18 java reflection annotations

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

implements Library.Operation: true
has @Library.Marker: false
Tada!
Run Code Online (Sandbox Code Playgroud)

Library.java:

package com.example.gotchas;

public class Library {
    private Library() {}

    public @interface Marker {}

    public interface Operation {
        public void execute(); 
    }
}
Run Code Online (Sandbox Code Playgroud)

MyOperation.java:

package com.example.gotchas;

@Library.Marker
public class MyOperation implements Library.Operation {
    @Override public void execute() {
        System.out.println("Tada!");
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Boz*_*zho 32

您必须@Retention为注释定义:

@Retention(RetentionPolicy.RUNTIME)
public @interface Marker {}
Run Code Online (Sandbox Code Playgroud)

否则,注释不会在运行时保留.

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

作为旁注 - 将注释定义为内部类并不常见.

  • [RetentionPolicy javadoc](http://download.oracle.com/javase/6/docs/api/java/lang/annotation/RetentionPolicy.html)中的更多细节:*RUNTIME - 注释将被记录在类文件中编译器并在运行时由VM保留,**因此可以反射性地阅读**.* (4认同)