[英]Understanding 'TypeElement' and 'DeclaredType' interface in java
这两个接口的一种用法,就是编写注释处理器。
作为一个Java初学者,我发现这两个包添加的间接级别: javax.lang.model.element
和javax.lang.model.type
提供有关Java interface
和Java class
混淆的元数据。
......
java doc评论说,
TypeElement
表示class
或interface
程序元素。 提供对有关类型及其成员的信息的访问。 请注意,enum
类型是一种类,注释类型是一种interface
。
DeclaredType
表示声明的类型,可以是class
类型或interface
类型。 这包括参数化类型,例如java.util.Set<String>
以及原始类型。
两者的区别:
虽然
TypeElement
表示class
或interface
元素 ,但DeclaredType
表示class
或interface
类型 ,后者是前者的使用(或调用 )。
如何区分行话元素和类型 ? 例如: class
元素与class
类型有何不同? 请帮我举个例子。
元素是组成软件所用的部分,即ExecutableElement
,顾名思义,其中包含可执行代码,描述一种存储类型的VariableElement
和将它们结合在一起的TypeElement
。 Java编程语言(作为一种面向对象的语言)的一个特殊属性是,没有顶级函数,也没有没有定义TypeElement
全局变量。
换句话说,如果您编写Java程序,则将始终具有至少一个包含至少一个类型声明的.java
源文件。 该TypeElement
可能至少包含一个ExecutableElement
来构成有用的软件。 TypeElement
可以包含多个ExecutableElement
, VariableElement
和嵌套的TypeElement
。 那就是程序的结构 。
在声明成员或局部变量时,以及在声明超类或-interface时,都使用类型 。 但是让我们关注变量,以更好地理解:
变量可以具有编程语言固有的原始类型,也可以具有隐式存在的类型,例如,当存在类型X
,还可以在变量声明中使用数组类型X[]
,但只有声明的类型是必须具有对应的TypeElement
的类型,该类型表示开发人员已编写(或由工具生成)的内容。 泛型还允许您编写类型,例如,声明类型为Set<? extends Number>
的变量Set<? extends Number>
Set<? extends Number>
而Set
和Number
是声明的类型 ,具有相应的程序元素…
如何区分行话元素和类型? 例如:类元素与类类型有何不同? 请帮我举个例子。
您可以将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.