【问题标题】:annotation invisible?注释不可见?
【发布时间】:2010-09-10 21:36:32
【问题描述】:

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

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

库.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();
        }
    }
}

【问题讨论】:

    标签: java reflection annotations


    【解决方案1】:

    你必须为你的注解定义@Retention

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

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

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

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

    【讨论】:

    • 同意。默认情况下,注释不会在运行时保留......在编译时它被删除。因此,当您运行测试代码时,注释不再是编译代码的一部分。
    • RetentionPolicy javadoc 中的更多详细信息:RUNTIME - 注释将由编译器记录在类文件中,并在运行时由 VM 保留,因此可以反射性地读取它们.
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2011-04-17
      • 2021-08-17
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多