In Java 8, Class
appears to have gained methods to get an AnnotatedType
view of its superclasses and its superinterfaces.
How can you convert a Class
to its own AnnotatedType
? Does that question even make sense?
From what I can tell, an AnnotatedType
has-a Type
, not is-a Type
. It's an AnnotatedElement
, though; it's all very messy.
I have searched through the Javadocs to no avail, so far.
So I finally got an acceptable understanding of the AnnotatedType
interface. Here's a working Java 8 example to illustrate one of its uses
public static void main(String[] args) {
Class<?> fooClass = Foo.class;
AnnotatedType type = fooClass.getAnnotatedSuperclass();
System.out.println(type);
System.out.println(Bar.class == type.getType());
System.out.println(Arrays.toString(type.getAnnotations()));
System.out.println(Arrays.toString(type.getDeclaredAnnotations()));
}
public static class Bar {
}
public static class Foo extends @Custom Bar {
}
// So that annotation metadata is available at run time
@Retention(RetentionPolicy.RUNTIME)
// TYPE_USE being the important one
@Target(value = {ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE,
METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER, TYPE_USE})
public @interface Custom {
}
This prints
sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl@1d44bcfa
true
[@com.testing.Test$Custom()]
[@com.testing.Test$Custom()]
The AnnotatedType
interface states
AnnotatedType
represents the potentially annotated use of a type in the program currently running in this VM.
and Class#getAnnotatedSuperclass()
javadoc states
Returns an
AnnotatedType
object that represents the use of a type to specify the superclass of the entity represented by thisClass
object.
I've made potentially bold in the AnnotatedType
javadoc because it makes it clear that the type usage doesn't have to be annotated. If you had
public static class Bar {}
...
Bar.class.getAnnotatedSuperclass(); // returns Class instance for java.lang.Object
This is a use case that wasn't possible in Java 7 and lower because you could not annotate type usages (see some examples here). In Java 8, however, you can do
public static class Foo extends @Custom Bar {
where the type Bar
is used as a super class and its usage is annotated with @Custom
. It is therefore an AnnotatedType
. Therefore, Foo.class.getAnnotatedSuperClass()
will return an AnnotatedType
instance for that usage.
How can you convert a
Class
to its ownAnnotatedType
? Does that question even make sense?
The question doesn't make sense. This is because a Class
object holds self-contained metadata about a class. By self-contained, I mean everything that can be deduced from the class' .class
file (or actual declaration). You cannot deduce any usages of the type anywhere else and therefore it cannot be converted to any AnnotatedType
for itself.
You can have
public static class Foo extends @Custom Bar {}
public static class Zoom extends @Custom Bar {}
public static class Doing extends @Custom Bar {}
There is an AnnotatedType
instance for each of the above uses of Bar
, but which one would you chose to convert a [Bar] Class
to its own AnnotatedType
?
Here's a simple example showing the usage of getAnnotatedSuperclass()
:
import java.lang.annotation.*;
public class AnnotationTest {
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface First { }
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface Second { }
class A { }
class B extends @First @Second A { }
public static void main(String[] args) {
Annotation[] anns = B.class.getAnnotatedSuperclass().getAnnotations();
System.out.printf("There are %d annotations on B's use of its superclass.%n", anns.length);
for (Annotation a : anns)
System.out.println(a.annotationType().getName());
}
}
The output from this program is:
There are 2 annotations on B's use of its superclass.
AnnotationTest$First
AnnotationTest$Second
Note the distinction of annotations occurring at the use of B's superclass (namely A) as opposed to the declaration of A itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With