【问题标题】:Accessing annotation of an enum referenced by an implemented interface访问由已实现接口引用的枚举的注释
【发布时间】:2019-12-05 09:57:51
【问题描述】:

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

@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
}

我通过向公共接口添加返回枚举类的反射信息的方法找到了一种解决方法,如下所示:

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);
}

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

谢谢

【问题讨论】:

    标签: java enums interface annotations


    【解决方案1】:

    您不需要通过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 实现,为了让思考“更安全”,请将“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());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-11
      • 2020-11-28
      • 2016-09-03
      • 2023-03-04
      相关资源
      最近更新 更多