繁体   English   中英

了解Java中的'TypeElement'和'DeclaredType'接口

[英]Understanding 'TypeElement' and 'DeclaredType' interface in java

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

作为一个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 那就是程序的结构


在声明成员或局部变量时,以及在声明超类或-interface时,都使用类型 但是让我们关注变量,以更好地理解:

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

如何区分行话元素和类型? 例如:类元素与类类型有何不同? 请帮我举个例子。

您可以将DeclaredType (类型)视为类的泛型类型(例如List<String> ); 与本质上忽略通用类型(例如List )的TypeElement (元素)相比。


您可以从元素开始,并建立通用类型:

// 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是一个具体的DeclaredType例如List<String>

关于此概念的一些额外见解为我提供了Types#getDeclaredType方法的javadoc:

返回与类型元素和实际类型参数相对应的类型。 例如,给定{@code Set}的type元素和{@code String}的类型镜像,此方法可用于获取参数化类型{@code 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);
    }
}

希望能有所帮助...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM