【问题标题】:Obtain an enum value via an annotation value in Java [duplicate]通过Java中的注释值获取枚举值[重复]
【发布时间】:2013-02-21 15:34:42
【问题描述】:

我正在尝试使用与枚举值关联的注释字符串值,以获得对关联枚举值的引用。

我最终卡在了中途......目前我有以下开发代码:

注释代码:

public @interface MyCustomAnnotation{
    String value();
}

枚举代码:

public enum MyEnum{
    @MyCustomAnnotation("v1")
    VALUE1,
    @MyCustomAnnotation("v2")
    VALUE2,
    @MyCustomAnnotation("v3")
    VALUE3,
}

使用枚举注解:

String matchString = "v1";
MyEnum myEnumToMatch;

// First obtain all available annotation values
for(Annotation annotation : (MyEnum.class).getAnnotations()){
    // Determine whether our String to match on is an annotation value against
    // any of the enum values
    if(((MyCustomAnnotation)annotation).value() == matchString){
        // A matching annotation value has been found
        // I need to obtain a reference to the corrext Enum value based on
            // this annotation value
        for(MyEnum myEnum : MyEnum.values()){
            // Perhaps iterate the enum values and obtain the individual
                    // annotation value - if this matches then assign this as the
                    // value.
            // I can't find a way to do this - any ideas?
            myEnumToMatch = ??
        }
    }
}

提前致谢。

【问题讨论】:

  • 您不能真正使用MyEnum.values(),因为注释附加到代码元素,而不是对象实例。您必须使用反射来访问存储枚举值常量的MyEnum 的静态字段。 MyEnum.class.getAnnotations() 也不会返回任何内容,因为 MyEnum 类本身没有任何注释,因此循环不会运行。
  • 您是否真的在调试器中启动了您的代码以实际查看程序状态并查看返回的值是什么?!
  • 最终需要什么?
  • @millimoose - 注释可以附加到类、方法、字段甚至局部变量,所以不确定“注释附加到代码元素,而不是对象实例”是什么意思。
  • @parsifal 它们不能附加到 arbitrary 对象实例(如枚举值,或者说随机字符串)。只有代表代码元素的对象才带有注释。

标签: java enums annotations


【解决方案1】:

在枚举中有一个字段会更容易,像这样:

public enum MyEnum {
    VALUE1("v1"),
    VALUE2("v2"),
    VALUE3("v3");

    private String displayValue;

    private MyEnum(string s) {
        this.displayValue = s;
    }

    public String getDisplayValue() {
        return displayValue;
    }
}

然后在您的匹配循环中,您只需遍历 MyEnum.values() 并寻找具有正确 displayValue 的那个。

【讨论】:

  • 这正是我所需要的,也是一个不错的解决方案,非常感谢。
【解决方案2】:

我完全同意@MichaelMyers 的观​​点,即最好为枚举添加一个值,而不是使用注释。但是,下面的代码应该可以帮助您了解注释是如何附加到枚举值的。

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    String value();
}

public enum Example {
    @MyAnno("v1")   FOO, 
    @MyAnno("v2")   BAR, 
    @MyAnno("v3")   BAZ
}


public static void main(String[] argv)
throws Exception {
    for (Field field : Example.class.getDeclaredFields()) {
        System.out.println(field.getName());
        for (Annotation anno : field.getAnnotations()) {
            if (anno instanceof MyAnno) {
                MyAnno myAnno = (MyAnno)anno;
                System.out.println("   anno = " + myAnno.value());
            }
        }
    }
}

【讨论】:

    【解决方案3】:

    枚举常量是enum 类的常规字段,因此您必须通过反射访问它们:

    for (Field enumValue : MyEnum.class.getDeclaredFields()) {
        MyAnnotation annotation = enumValue.getAnnotation(MyAnnotation.class);
        if (annotation != null) {
            System.out.printf("Field '%s' is annotated with @MyAnnotation with value '%s'\n",
                    enumValue.getName(),
                    annotation.value());
        } else {
            System.out.printf("Field '%s' is not annotated with @MyAnnotation\n", enumValue.getName());
        }
    }
    

    请注意,这还将包括一个名为 $VALUES 的内部字段,其中包含一个包含所有枚举值的数组。您可以使用例如过滤掉它if (enumValue.isSynthethic()) { ... }.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-19
      • 1970-01-01
      • 2012-08-11
      • 2012-12-28
      • 2023-03-31
      • 2011-10-27
      相关资源
      最近更新 更多