[英]How to get the type of a field in an annotation processor?
I'm trying to write an annotation to check if an object is immutable at runtime.我正在尝试编写注释来检查对象在运行时是否不可变。 In order to do so, I check if the class of the object is final and then if all its attributes are also final.
为此,我检查对象的类是否是最终的,然后检查它的所有属性是否也是最终的。 And then, I want to check the same thing recursively for the type of each field if it's not a primitive type.
然后,如果每个字段不是原始类型,我想递归地检查相同的事情。
Here a piece of code:这里有一段代码:
for (Element subElement : element.getEnclosedElements()) {
if (subElement.getKind().isField()) {
isFinal=false;
for(Modifier modifier : subElement.getModifiers()) {
if (modifier.equals(Modifier.FINAL)) {
isFinal=true;
break;
}
}
if (!isFinal) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Field "+element+" is not immutable because it is not final");
} else {
// Here I want to restart my method recursively
}
}
}
How can I get my method to start all over again with the type of my field?我怎样才能让我的方法重新开始我的领域类型? How can I retrieve the type of the field, which is here a
javax.lang.model.element.Element
?如何检索字段的类型,这里是
javax.lang.model.element.Element
?
Edit: I need the type as declared in the containing class, which needs to be a final class to avoid any kind of mutability.编辑:我需要在包含类中声明的类型,它需要是最终类以避免任何类型的可变性。
I've been able to do it with Square's javapoet ClassName
class:我已经能够使用Square 的 javapoet
ClassName
类来做到这一点:
Element element = ...
ClassName className = ClassName.get(element.asType());
String name = className.toString();
If, for example, the annotated field is a String
, it will return Java.lang.String
.例如,如果带注释的字段是
String
,它将返回Java.lang.String
。 I'm open to a better solution than this one.我愿意接受比这个更好的解决方案。
I think我认为
String type = element.asType().toString();
also gets the fully qualified name of the type of the fields.还获取字段类型的完全限定名称。
I never have needed javax.lang.model
before.我以前从来不需要
javax.lang.model
。 If you intend to check things at runtime, I'd go through java.lang.Class
and java.lang.reflect.Field
instead.如果您打算在运行时检查内容,我会通过
java.lang.Class
和java.lang.reflect.Field
来代替。 There you can use getType
to obtain the type of the field.您可以在那里使用
getType
来获取字段的类型。 You can also have a look at all fields, including inherited ones, using getFields
.您还可以使用
getFields
查看所有字段,包括继承的字段。 Or you can look at ancestor classes and their declared fields, to get at private ones as well.或者您可以查看祖先类及其声明的字段,以获取私有的。
Edit: the following consideration appears to be no longer relevant编辑:以下考虑似乎不再相关
Notice that even that type information will return the declared type, ie the type as it is written in the source code.请注意,即使是该类型信息也将返回声明的类型,即在源代码中写入的类型。 The field might still hold a reference to a derived class at runtime.
该字段在运行时可能仍保留对派生类的引用。 Possible counter-measures would be having all those classes declared
final
, so that there can be no derived classes, or tracing all assignments to those fields, which would mean major static data flow analysis.可能的对策是将所有这些类都声明为
final
,这样就不会有派生类,或者跟踪对这些字段的所有分配,这将意味着主要的静态数据流分析。 Not sure that's worth the effort.不确定这是否值得付出努力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.