我正在做一个项目,我的主管希望我能够通过注释处理器获取枚举常量的值。例如来自以下枚举定义:
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] 的数组。
请注意,因为我在注释处理器中工作,所以我使用了 Element基于反射(不是基于 Class 的反射)。
我的阅读VariableElement文档让我相信这是不可能的。
Note that not all final fields will have constant values. In particular, enum constants are not considered to be compile-time constants.
有谁知道让这个工作的方法?
感谢您抽出时间来阅读!
--贝卡
最佳答案
我们最终为这个项目做的是在运行注释处理器之前编译所有枚举。如果在运行注释处理器之前已经编译了一个类,则可以使用 Class 访问有关它的信息。基于反射。
在这种情况下,首先编译枚举是可行的,因为枚举的类被传递给其他类的注释(枚举用于定义一些下拉列表)。
这是用于获取枚举常量名称及其值的代码。其中 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...
}
Here如果您想要更多上下文,则是完整的拉取请求。实际的枚举解析由 ComponentProcessor 文件处理。
关于java - 如何从注释处理器读取枚举常量的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62161602/