Understanding 'TypeElement' and 'DeclaredType' interface in java

One usage of these two interface, is to write annotation processor.

As a java beginner, I find the level of indirection that is added by these two packages: javax.lang.model.element & javax.lang.model.type to provide metadata about java interface and java class confusing.

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

在这里输入图像描述

java doc comments say,

TypeElement represents a class or interface program element. Provides access to information about the type and its members. Note that an enum type is a kind of class and an annotation type is a kind of interface .

DeclaredType represents a declared type, either a class type or an interface type. This includes parameterized types such as java.util.Set<String> as well as raw types.

Difference between the two:

While a TypeElement represents a class or interface element, a DeclaredType represents a class or interface type, the latter being a use (or invocation) of the former.

How do I differentiate the jargon element from type? For example: How is class element different from class type? Please help me with an example.


The elements are the parts that you use to compose a software, ie ExecutableElement s which, as the name suggests, contain executable code, VariableElement s which describe a kind of storage and TypeElement s which hold these together. It's a special property of the Java programming language (as an object oriented language) that there are no top-level functions nor global variables without a TypeElement , in which they are defined.

In other words, if you write a Java program, you will always have at least one .java source file containing at least one type declaration. That TypeElement will likely contain at least one ExecutableElement to make up a useful software. The TypeElement may contain multiple ExecutableElement s, VariableElement s and nested TypeElement s. That's the structure of your program.


A type is something which you use whenever you declare a member or local variable, but also when declaring a super class or -interface. But let's focus on variables, for a better understanding:

A variable can have a primitive type, which is intrinsic to the programming language, it can also have a type whose existence is implied, eg when there is a type X , you can also use the array type X[] in a variable declaration, but only the declared type is a type which must have a corresponding TypeElement , representing something, a developer has written (or has been generated by a tool). Generics also allow you to compose types, eg declare a variable of type Set<? extends Number> Set<? extends Number> whereas Set and Number are declared types which have corresponding program elements…


How do I differentiate the jargon element from type? For example: How is class element different from class type? Please help me with an example.

You can think of the DeclaredType (type) as the generic type of a class (eg List<String> ); compared to TypeElement (element) which essentially ignores the generic type (eg List ).


You can start with elements, and build up generic types:

// 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);

So first of all I must admit I am no Java Guru, but found your question interesting and spent some time learning about it. Here's what I found out.

In my opinion the whole concept is hugely connected with generics. As mentioned in this answer: https://stackoverflow.com/a/2127320/4250114

TypeElement is a statically defined type eg List<E> , List<? extends SomeType> List<? extends SomeType> . Whereas DeclaredType is a concrete one like List<String> .

Some extra insight about the concept gave me the javadoc of Types#getDeclaredType method:

Returns the type corresponding to a type element and actual type arguments. Given the type element for {@code Set} and the type mirror for {@code String}, for example, this method may be used to get the parameterized type {@code Set}.

As mentioned in another answer in the cited question (https://stackoverflow.com/a/2127266/4250114) if you want to learn some more the paper of Gilad Bracha and David Ungar should be a good place(at least I am going to ;) ).

Of course you could also experiment on your own. Eg I have written such Processor that I was examining with debugger:

@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);
    }
}

Hope it helped...

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

上一篇: 是否需要在脚本的末尾关闭Psycopg2连接?

下一篇: 在java中理解'TypeElement'和'DeclaredType'接口