Java 8: Class to AnnotatedType
java, java-8
Solution
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 this `Class` 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 own `AnnotatedType`? 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`?
Problem
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.