开发者

annotation invisible?

This puzzles me. I have a class with a custom annotation and I can't seem to verify that the annotation is present. What am I doing wrong here? If I run MyOperationTest (see below), I get this as a result:

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 hasLibra开发者_运维百科ryMarker =
                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();
        }
    }
}


You have to define @Retention for your annotation:

@Retention(RetentionPolicy.RUNTIME)
public @interface Marker {}

Otherwise the annotation is not retained at runtime.

(You can also add explicit @Target(ElementType.TYPE) if you want to limit the usage of your annotation only on classes)

As a sidenote - it is not a common practice to define annotations as inner classes.


By default, annotation retention policy is CLASS, which does not make your annotation available to reflection. You should qualify it when declaring the annotation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜