An Element
can represent, as of Java 13:
- A module declaration -
ModuleElement
- A package declaration -
PackageElement
- An interface, class, enum, or annotation type -
TypeElement
- A constructor, method, or initializer -
ExecutableElement
- A field, enum constant, method or constructor parameter, local variable, resource variable, or exception parameter -
VariableElement
- A type parameter -
TypeParameterElement
Each of these elements can have annotations present. For example:
module-info.java:
@Foobar
module example {
exports com.example;
}
package-info.java:
@Foobaz
package com.example;
Foo.java:
package com.example;
@Baz
public class Foo<@Qux T> {
private final T bar;
public Foo(T bar) {
this.bar = bar;
}
@Override
public String toString() {
return "Foo{bar= " + bar + "}";
}
}
- The module
example
, which would be a ModuleElement
, has a @Foobar
annotation present.
- The package
com.example
, which would be a PackageElement
, has a @Foobaz
annotation present.
- The class
Foo
, which would be a TypeElement
, has a @Baz
annotation present.
- The type parameter
T
, which would be a TypeParameterElement
, has a @Qux
annotation present.
- The field
bar
, which would be a VariableElement
, has no annotations present.
- The constructor
#Foo(T)
, which would be an ExecutableElement
, has no annotations present.
- The constructor's parameter
bar
, which would be a VariableElement
, has no annotations present.
- The method
#toString()
, which would be an ExectuableElement
, has an @Override
annotation present.
You can get the annotations present on these elements via the methods of the AnnotatedConstruct
interface, which Element
extends.
The method Element#getEnclosingElement()
returns, unsurprisingly, the Element
which encloses the current Element
, if any. So if you were to invoke that method on the ExecutableElement
representing the method #toString()
then you'd get the TypeElement
representing the class Foo
.