如何获取注释处理器中的字段类型?

时间:2012-07-11 22:44:00

标签: java annotations java-6 annotation-processing

我正在尝试编写一个注释来检查一个对象在运行时是否是不可变的。为了做到这一点,我检查对象的类是否是最终的,然后检查它的所有属性是否也是最终的。然后,如果它不是基本类型,我想以递归方式检查每个字段的类型。

这是一段代码:

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
        }
    }
}

如何使用我的字段类型让我的方法重新开始?如何检索字段的类型,这是javax.lang.model.element.Element

编辑:我需要在包含类中声明的类型,它必须是一个最终类,以避免任何类型的可变性。

3 个答案:

答案 0 :(得分:1)

我已经能够使用Square's javapoet ClassName类:

Element element = ...
ClassName className = ClassName.get(element.asType());
String name = className.toString();

例如,如果带注释的字段是String,则会返回Java.lang.String。我愿意接受比这更好的解决方案。

答案 1 :(得分:1)

我认为

String type = element.asType().toString();

还将获取字段类型的全限定名称。

答案 2 :(得分:0)

我以前从未需要javax.lang.model。如果您打算在运行时检查一下,我会通过java.lang.Classjava.lang.reflect.Field来代替。在那里,您可以使用getType来获取字段的类型。您还可以使用getFields查看所有字段,包括继承的字段。或者您可以查看祖先类及其声明的字段,以获取私有类。

编辑:以下考虑因素似乎不再相关

请注意,即使该类型信息也将返回声明的类型,即在源代码中写入的类型。该字段可能仍然在运行时保存对派生类的引用。可能的反措施是将所有这些类声明为final,这样就不会有派生类,或者跟踪这些字段的所有赋值,这将意味着主要的静态数据流分析。不确定这是值得的。