zero_cool zero_cool - 3 months ago 11
Java Question

How to create an instance out of a TypeMirror

I have an annotation that receives a "dynamic" parameter according to this idiom, i.e. a parameter of an interface type. In short:

public interface MyInterface {}

public @interface MyAnnotation {
Class<? extends MyInterface> value();
}


Now, to evaluate this parameter I need to create an instance of the provided implementation. The answer linked above does this at runtime. I am, however, writing a "real" (i.e. compile-time) annotation processor following this tutorial. When working with types you have to consider that they may not be compiled yet. The tutorial handles that (in that case to retrieve the the type's name) in the following way:


// Get the full QualifiedTypeName
try {
Class<?> clazz = annotation.type();
qualifiedSuperClassName = clazz.getCanonicalName();
simpleTypeName = clazz.getSimpleName();
} catch (MirroredTypeException mte) {
DeclaredType classTypeMirror = (DeclaredType) mte.getTypeMirror();
TypeElement classTypeElement = (TypeElement) classTypeMirror.asElement();
qualifiedSuperClassName = classTypeElement.getQualifiedName().toString();
simpleTypeName = classTypeElement.getSimpleName().toString();
}



So, to instantiate the type, in the
try
block I can use
newInstance()
. But what do I have to do in the
catch
block to create an instance? Or is it not possible because the type has not been compiled yet? In that case, how do I solve the "dynamic parameter" issue?

Edit: In my specific case I may resort to using a String parameter and interpreting it as a Groovy template. Still looking for answers though.

Answer

During annotation processing, in the general case it is not possible to construct an instance of any class being compiled. Remember that annotation processing runs inside the compiler, as a part of a multi-step process. There's no guarantee that a class and all its dependencies are actually compiled and ready to class-load at the time your annotation processor is executing.

Note also that your annotation declaration is invalid. Section 9.6.1 of the Java language specification lists the valid types of annotation elements, and a value of an user-defined interface is not one of them. At best what you can have is a Class<? extends MyInterface>, but then you have the same issues about how to instantiate it.

It sounds like your use case for annotation processing is very specialized. It would probably help if you opened a new question about the actual problem you're trying to solve, since there may be a better way to solve it than this.