我有一些Enum
类型的非null
变量(例如en1
)。问题是:如何获得与en1
变量引用的枚举常数相关的注释?
Try this (java reflection):
String field = En.AAA.name();
En.class.getField(field).getAnnotations();
它应该可以得到AAA
的注释。
如作者所料:
en1.getClass().getField(((Enum)en1).name()).getAnnotations();
适合他:)
我已经说过了:
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 confusion case
我刚从你的评论中看到你已经找到了答案。我只是想对其他感兴趣的人说一下,为了让它工作,那些注释必须用正确的保留策略声明,就像这样:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Anno1 {
// ...
}
如果没有这个,它们将无法在运行时访问。
进一步阅读:
- JavaDoc: RetentionPolicy
- 维基百科:Java注释
如果您正在使用像Proguard这样的混淆器,您可能会发现枚举字段已经被重命名,而.name()
仍然返回字段的原始名称。例如,这个enum…
enum En {
FOO,
BAR
}
…
enum En {
a,
b
}
…但是En.FOO.name()
仍然会返回"FOO"
,导致getField(En.FOO.name())
失败,因为它期望该字段被命名为"a"
。
如果您想从混淆的代码中获得特定enum字段的Field
,您可以这样做:
for (Field field : En.class.getDeclaredFields()) {
if (field.isEnumConstant()) {
try {
if (en1 == field.get(null)) {
Annotation[] annotations = field.getAnnotations();
}
} catch (IllegalAccessException e) {
//
}
}
}
除了现有的答案,如果你控制枚举类(可以编辑它),你可以简单地向枚举添加一个方法来获取所需的注释,即
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)