如何从 TypeMirror 创建实例

How to create an instance out of a TypeMirror

我有一个注释根据 this idiom 接收一个 "dynamic" 参数,即接口类型的参数。简而言之:

public interface MyInterface {}

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

现在,为了评估此参数,我需要创建所提供实现的一个实例。上面链接的答案在运行时执行此操作。但是,我正在 this tutorial 之后编写一个 "real"(即编译时)注释处理器。使用类型时,您必须考虑到它们可能尚未编译。本教程通过以下方式处理(在这种情况下检索类型的名称):

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

因此,要实例化类型,在 try 块中我可以使用 newInstance()。但是我必须在 catch 块中做什么才能创建实例?还是因为类型尚未编译而不可能?那么,如何解决 "dynamic parameter" 问题?

编辑: 在我的特定情况下,我可能会求助于使用字符串参数并将其解释为 Groovy 模板。仍在寻找答案。

在注解处理过程中,一般情况下不可能构造任何正在编译的class实例。请记住,注释处理 在编译器 内部运行,作为多步骤过程的一部分。无法保证 class 及其所有依赖项实际上已编译并准备好 class-在执行注释处理器时加载。

另请注意,您的注释声明无效。 Section 9.6.1 of the Java language specification 列出有效的注解元素类型,用户自定义接口的值不是其中之一。充其量您可以拥有的是 Class<? extends MyInterface>,但是关于如何实例化它,您会遇到同样的问题。

听起来您的注释处理用例非常专业。如果您打开一个关于您要解决的实际问题的新问题,这可能会有所帮助,因为可能有比这更好的解决方法。

他删除了 Will Lp 的一个回答,因为它与 Groovy 有关,而不是 Java。

不过,我确实认为它是相关的。

当使用 Groovy 你实际上可以 pass a closure as a class parameter to an annotation.