Java 如何从注释处理器读取枚举常量的值?

Java 如何从注释处理器读取枚举常量的值?,java,enums,Java,Enums,我正在从事一个项目,我的主管希望我能够通过注释处理器获取枚举常量的值。例如,从以下枚举定义: public enum Animal { LION(5), GIRAFFE(7), ELEPHANT(2), private int value; Animal(int value) { this.value = value; } public int Value() { return value; }

我正在从事一个项目,我的主管希望我能够通过注释处理器获取枚举常量的值。例如,从以下枚举定义:

public enum Animal {
    LION(5),
    GIRAFFE(7),
    ELEPHANT(2),

    private int value;

    Animal(int value) {
        this.value = value;
    }

    public int Value() {
        return value;
    }
}
他们希望我编译一个[5,7,2]的数组

请注意,因为我在注释处理器中工作,所以我使用的是基于反射(而不是基于反射)

我对文档的阅读使我相信这是不可能的

请注意,并非所有最终字段都具有常量值。特别是,枚举常量不被视为编译时常量

有人知道如何让它工作吗

感谢您抽出时间阅读此文章!
--Beka

我们在运行注释处理器之前编译了所有的枚举。如果在运行注释处理器之前已经编译了一个类,那么可以使用基于注释的反射来访问有关该类的信息

在这种情况下,首先编译枚举是可行的,因为枚举的类被传递给其他类上的注释(枚举用于定义一些下拉列表)

下面是用于获取枚举常量及其值的代码。其中optionElem是表示枚举类的元素

private <E extends Enum<E>> boolean tryAddOptionList(Element optionElem) {
    String className = optionElem.asType().toString();

    // Get the class.
    Class clazz = null;
    try {
      clazz = Class.forName(className);
    } catch (ClassNotFoundException e) {
      throw new IllegalArgumentException("OptionList Class: " + className + " is not available. " +
        "Make sure that it is available to the compiler.");
    }
    if (clazz == null) {
      return false;
    }

    // Get the getValue method.
    java.lang.reflect.Method getValueMethod = null;
    try {
      getValueMethod = clazz.getDeclaredMethod("getValue", new Class[] {});
    } catch (NoSuchMethodException e) {
      throw new IllegalArgumentException("Class: " + className + " must have a getValue() method.");
    }
    if (getValueMethod == null) {
      return false;
    }

    // Create a map of enum const names -> values.
    Map<String, String> namesToValues = Maps.newTreeMap();
    Object[] constants = clazz.getEnumConstants();
    for (Object constant : clazz.getEnumConstants()) {
        try {
          E enumConst = (E) constant;
          namesToValues.put(
            enumConst.name(),
            getValueMethod.invoke(enumConst, new Object [] {}).toString());
        } catch (Exception e) {}
    }
    // etc...
}
private boolean tryAddOptionList(元素optionElem){
String className=optionElem.asType().toString();
//去上课。
类clazz=null;
试一试{
clazz=Class.forName(className);
}catch(classnotfounde异常){
抛出新的IllegalArgumentException(“OptionList类:“+className+”不可用。”+
“确保编译器可以使用它。”);
}
if(clazz==null){
返回false;
}
//获取getValue方法。
java.lang.reflect.Method getValueMethod=null;
试一试{
getValueMethod=clazz.getDeclaredMethod(“getValue”,新类[]{});
}捕获(无此方法例外){
抛出新的IllegalArgumentException(“类:“+className+”必须有一个getValue()方法。”);
}
if(getValueMethod==null){
返回false;
}
//创建枚举常量名称->值的映射。
Map namesToValues=Maps.newTreeMap();
Object[]constants=clazz.getEnumConstants();
for(对象常量:clazz.getEnumConstants()){
试一试{
E enumConst=(E)常数;
namesToValues.put(
enumConst.name(),
调用(enumConst,新对象[]{}).toString();
}捕获(例外e){}
}
//等等。。。
}

如果您想要更多的上下文,则为完全拉取请求。实际上,枚举解析由ComponentProcessor文件处理。

您可以迭代该枚举的子项,如果其中一个是a,则可以获得其值谢谢您的回答!但是我很困惑,VariableElement的文档不是说不能用枚举常量来实现这一点吗?(参见OP中的引文)如何使用VariableElement获取值?它还说“表示字段,枚举常量,…”,因此我认为这是可能的问题不是枚举常量不是编译时常量,因为您在编译时仍然知道它们的值,例如,
动物。众所周知,长颈鹿持有
动物
类型的物体,其
名称()==“GIRAFFE”
序数()==1
。问题是,您想要获取字段
Animal.value
,即
Animal.GIRAFFE.value
,它是在构造函数中分配的。可以使用编译器树api来完成。您可以分享完整的示例吗,因为我有类似的要求?嗯,我不知道如何才能使示例更完整@prakash.panjwani我已经提供了处理代码,以及到pull请求的链接,在那里我实现了完整的系统=),但是如果您有任何具体问题,我可以尽力回答!