获取枚举类型变量的注释

时间:2011-08-31 08:00:07

标签: java reflection enums annotations

我有Enum类型的非null变量(例如en1)。问题是:如何获取与en1变量引用的枚举常量相关的注释?

5 个答案:

答案 0 :(得分:33)

试试这个(java反射):

String field = En.AAA.name();
En.class.getField(field).getAnnotations();

它应该从AAA获取注释。

编辑:

正如作者所说:

en1.getClass().getField(((Enum)en1).name()).getAnnotations(); 

适合他:)

答案 1 :(得分:21)

正如我已经提出的那样:

en1.getClass().getField(((Enum)en1).name()).getAnnotations();

更清楚:

String name = e.name(); // Enum method to get name of presented enum constant
Annotation[] annos = e.getClass().getField(name).getAnnotations(); // Classical reflection technique

在这种情况下,我们无需知道真正的en1类。

另请参阅:remark about obfuscated case

答案 2 :(得分:7)

我刚从你的评论中读到你已经找到了答案。我只是想对其他感兴趣的人说,为了使其工作,这些注释必须使用正确的保留策略声明,如下所示:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Anno1 {
   // ...
}

如果没有这个,它们将无法在运行时访问。

进一步阅读:

答案 3 :(得分:4)

如果您使用的是混淆器,例如Proguard,您可能会发现枚举字段已重命名,而.name()仍然返回该字段的原始名称。例如,这个枚举......

enum En {
    FOO,
    BAR
}

......在ProGuarding之后会成为......

enum En {
    a,
    b
}

...但En.FOO.name()仍会返回"FOO",导致getField(En.FOO.name())失败,因为它希望该字段的名称为"a"

如果要从模糊代码中获取特定枚举字段的Field,可以执行以下操作:

for (Field field : En.class.getDeclaredFields()) {
    if (field.isEnumConstant()) {
        try {
            if (en1 == field.get(null)) {
                Annotation[] annotations = field.getAnnotations();
            }
        } catch (IllegalAccessException e) {
            // 
        }
    }
}

答案 4 :(得分:2)

除了现有的答案之外,如果你控制枚举类(可以编辑它),你可以简单地在枚举中添加一个方法来获取所需的注释,即

AnnotationClass getAnnotation(){
   Field field = this.getClass().getField(this.name());
   return field.getAnnotation(AnnotationClass.class);       
}

或其所有注释:

Annotation[] getAnnotations(){
   Field field = this.getClass().getField(this.name());
   return field.getAnnotations();
}

调整上面的代码来处理异常(NoSuchFieldException和SecurityException)。