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请求的链接,在那里我实现了完整的系统=),但是如果您有任何具体问题,我可以尽力回答!