我有一些非null
的变量(例如en1
),其类型为Enum
。问题是:如何获取与被en1
变量引用的枚举常量相关的注释?
试试这个(使用Java反射):
String field = En.AAA.name();
En.class.getField(field).getAnnotations();
这应该可以帮助你获取来自AAA
的注解。
编辑:
正如作者所假设的:
en1.getClass().getField(((Enum)en1).name()).getAnnotations();
对他有效 :)
.name()
比使用.toString()
更安全,因为toString()
可能被重载(而name()
是final
)。 - Joachim SauerEn
常量中哪个被赋予了en1
。此外,在你回答之前我已经编辑了我的问题并加强了要求。 - Timofey GorshkovisAnnotationPresent()
总是返回 false
。 - rds我已经提供过了:
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
的真实类别。我看到你的评论已经找到了答案。我只是想提醒其他感兴趣的人,在这种情况下,为了使其生效,这些注释必须已经使用正确的保留策略进行声明,例如:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Anno1 {
// ...
}
如果没有这个,它们将无法在运行时访问。
更多阅读:
@Target
注释,则其中至少应该有ElementType.FIELD
。 - Timofey Gorshkov如果您正在使用类似于Proguard的混淆器,则可能会发现枚举字段已被重命名,而.name()
仍然返回该字段的原始名称。例如,此枚举...
enum En {
FOO,
BAR
}
经过ProGuard处理后,它会变成这样...
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) {
//
}
}
}
根据现有的答案,如果您控制枚举类(可以编辑它),您可以简单地添加一个方法到枚举中来获取所需的注释,例如:
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)。
Object en1 = ...; Annotation[] anns = magic(en1);
吗?那我会问为什么en1
是Object
类型而不是En
类型。你能提供一些类似的示例代码吗? - musiKken1.getClass().getField(((Enum)en1).name()).getAnnotations();
。 - Timofey Gorshkoven1
是某个enum
类型”是指en1
是Enum
的一个实例。 - Timofey Gorshkov