在java中理解'TypeElement'和'DeclaredType'接口

这两个接口的一个用法是编写注释处理器。

作为一名java初学者,我发现这两个包添加的间接级别: javax.lang.model.elementjavax.lang.model.type以提供关于java interface和java class元数据混淆。

在这里输入图像描述 .........

在这里输入图像描述

java doc评论说,

TypeElement表示一个classinterface程序元素。 提供有关类型及其成员的信息。 请注意, enum类型是一种类,注释类型是一种interface

DeclaredType表示声明的类型, class类型或interface类型。 这包括参数化类型,例如java.util.Set<String>以及原始类型。

两者之间的区别:

虽然TypeElement表示classinterface元素,但是DeclaredType表示classinterface类型,后者是前者的使用(或调用)。

如何区分行话元素和类型? 例如: class元素如何与class类型不同? 请以示例帮助我。


这些元素是用来组成软件的部分,也就是说,正如名称所暗示的那样, ExecutableElement包含可执行代码,描述一种存储的VariableElement和将它们组合在一起的TypeElement 。 它是Java编程语言(作为面向对象的语言)的一个特殊属性,没有顶级函数,也没有没有TypeElement全局变量,在这些变量中定义了它们。

换句话说,如果您编写一个Java程序,您将始终至少有一个.java源文件包含至少一个类型声明。 该TypeElement可能包含至少一个ExecutableElement来组成一个有用的软件。 TypeElement可能包含多个ExecutableElementVariableElement和嵌套的TypeElement 。 这是你程序的结构。


一个类型是你在声明一个成员或局部变量时使用的东西,当你声明一个超类或者接口的时候也是如此。 但让我们关注变量,以便更好地理解:

一个变量可以有一个原始类型,它是编程语言固有的,它也可以有一个存在隐含的类型,例如当有一个类型X ,你也可以在变量声明中使用数组类型X[] ,但只有声明的类型是必须具有相应TypeElement的类型,表示开发人员已写入(或已由工具生成)的内容。 泛型也允许你组合类型,例如声明一个类型为Set<? extends Number>的变量Set<? extends Number> Set<? extends Number>SetNumber是具有相应程序元素的声明类型...


如何区分行话元素和类型? 例如:类元素如何与类类型不同? 请以示例帮助我。

你可以把DeclaredType (type)看作是一个类的泛型类型(例如List<String> ); 与基本上忽略泛型类型的TypeElement (element)相比(例如List )。


您可以从元素开始,然后构建泛型类型:

// Utility elements that come with javax.annotation.processing
Elements elements = processingEnv.getElementUtils();
Types types = processingEnv.getTypeUtils();

// These are elements, they never have generic types associated
TypeElement listElement = elements.getTypeElement(List.class.getName());
TypeElement strElement  = elements.getTypeElement(String.class.getName());

// Build a Type: List<String>
DeclaredType listStrType = types.getDeclaredType(
                               listElement, 
                               strElement.asType());

// Build a Type: List<List<String>>
DeclaredType listlistStrType = types.getDeclaredType(
                               listElement,
                               listElement.asType(),
                               listStrType);

所以首先我必须承认我不是Java Guru,但是发现你的问题很有趣,并花了一些时间来了解它。 这是我发现的。

在我看来,整个概念与泛型非常相关。 正如在这个答案中提到的:https://stackoverflow.com/a/2127320/4250114

TypeElement是静态定义的类型,例如List<E>List<? extends SomeType> List<? extends SomeType> 。 而DeclaredType是一个像List<String>的具体类。

关于这个概念的一些额外的见解给了我Types#getDeclaredType方法的javadoc:

返回对应于类型元素和实际类型参数的类型。 例如,给定{@code Set}的类型元素和{@code String}的类型镜像,此方法可用于获取参数化类型{@ Set}。

正如引用问题的另一个答案(https://stackoverflow.com/a/2127266/4250114)中提到的,如果您想了解更多,Gilad Bracha和David Ungar的论文应该是一个好地方(至少我要去至 ;) )。

当然你也可以自己做实验。 例如,我编写了一个我正在用调试器检查的处理器:

@SupportedAnnotationTypes({"annotationProcessor.MyAnnotation"})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class AnnotationProcessor extends AbstractProcessor {

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        final Map.Entry<TypeElement, DeclaredType> collection = getType("java.util.Collection");
        final Map.Entry<TypeElement, DeclaredType> string = getType("java.util.String");
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {
        return false;
    }


    private Types typeUtils() {
        return processingEnv.getTypeUtils();
    }

    private Map.Entry<TypeElement, DeclaredType> getType(String className) {
        TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(className);
        DeclaredType declaredType = typeUtils().getDeclaredType(typeElement);
        return new HashMap.SimpleEntry<>(typeElement, declaredType);
    }
}

希望它有帮助...

链接地址: http://www.djcxy.com/p/86441.html

上一篇: Understanding 'TypeElement' and 'DeclaredType' interface in java

下一篇: How To Do Recursive Observable Call in RxJava?