访问已实现接口引用的枚举的注解

Accessing annotation of an enum referenced by an implemented interface

我正在尝试访问由许多枚举 classes 实现的接口引用的枚举字段注释的参数。像这样:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface MyAnnotation {
    String someValue();
}

interface CommonInterface {}

enum FirstEnum implements CommonInterface{
    @MyAnnotation(someValue = "abc")
    A;
}

enum SecondEnum implements CommonInterface{
    @MyAnnotation(someValue = "cde")
    B;
}

void foo(CommonInterface enumValue){
   String someValue; // get the parameter value
}

我通过向 return 枚举 class 的反射信息的公共接口添加方法找到了解决此问题的方法,如下所示:

interface CommonInterface{
    Class<? extends CommonInterface> getEnumClass();
    String getName();
}

enum FirstEnum implements CommonInteface{
    @MyAnnotation(someValue = "abc")
    A;

    public Class<? extends CommonInteface> getEnumClass() {
        return getClass();
    }

    public String getName() {
        return name();
    }
}

void foo(CommonInterface enumValue){
    MyAnnotation myAnnotation = enumValue.getEnumClass().getField(enumValue.getName()).getAnnotation(MyAnnotation.class);
}

有没有更好的方法来做同样的事情?我看到一些解决方案,他们推荐一个包装器枚举 class,它将接口引用的枚举值作为构造函数参数。在我的例子中,这不是很可行,因为会有很多实现公共接口的枚举,每个枚举都有很多值,所以维护它不会很好。

谢谢

您不需要通过 CommonInterface 公开 getEnumClass(),在实例上调用 getClass() 就足够了。同样为什么调用你的方法 getName() 为什么不直接调用它 name() 所以它是由 Enum 隐式实现的?

你可以只做这样的事情,而不需要向 CommonInterface 添加任何方法:

void foo(CommonInterface enumValue) throws Exception {
    String name = enumValue.getClass().getMethod("name").invoke(enumValue).toString();
    MyAnnotation myAnnotation = enumValue.getClass().getField(name).getAnnotation(MyAnnotation.class);
    System.out.println(myAnnotation.someValue());
}

虽然这很危险,因为它假定 CommonInterface 的所有实现都是枚举,因此有一个 name() 方法。如果您有一个不是枚举的 CommonInterface 实现,请考虑 "safer" 将 "name" 方法添加到 CommonInterface:

interface CommonInterface {
    String name();
}

然后您的 "foo" 方法变为:

void foo(CommonInterface enumValue) throws Exception {
    MyAnnotation myAnnotation = enumValue.getClass().getField(enumValue.name()).getAnnotation(MyAnnotation.class);
    System.out.println(myAnnotation.someValue());
}