获取枚举类型变量的注释

Tim*_*kov 34 java reflection enums annotations

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

Tob*_*ias 34

试试这个(java反射):

String field = En.AAA.name();
En.class.getField(field).getAnnotations();
Run Code Online (Sandbox Code Playgroud)

它应该从你那里得到注释AAA.

编辑:

正如作者所说:

en1.getClass().getField(((Enum)en1).name()).getAnnotations(); 
Run Code Online (Sandbox Code Playgroud)

适合他:)

  • 使用`.name()`比使用`.toString()`更安全,因为`toString()`可能会重载(而`name()`是`final`). (9认同)
  • @rds - 确保你在`@interface`上使用`@Retention(RetentionPolicy.RUNTIME)`. (3认同)

Tim*_*kov 21

正如我已经提出的:

en1.getClass().getField(((Enum)en1).name()).getAnnotations();
Run Code Online (Sandbox Code Playgroud)

更清楚:

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

在这种情况下,我们不需要知道真正的类en1.

另请参阅:关于混淆案例的评论.


Ric*_* T. 7

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Anno1 {
   // ...
}
Run Code Online (Sandbox Code Playgroud)

没有它,它们将无法在运行时访问.

进一步阅读:


Jar*_*ard 5

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

enum En {
    FOO,
    BAR
}
Run Code Online (Sandbox Code Playgroud)

...在 ProGuarding 后会变成这样...

enum En {
    a,
    b
}
Run Code Online (Sandbox Code Playgroud)

...但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) {
            // 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)