如何从TypeMirror创建实例

时间:2016-08-30 08:38:09

标签: java annotation-processing

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

public interface MyInterface {}

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

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

// 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块中需要做些什么才能创建实例?或者是不可能的,因为尚未编译类型?在这种情况下,我如何解决“动态参数”问题?

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

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:0)

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

但是,我确实认为这是相关的。

使用Groovy时,您实际上可以pass a closure as a class parameter to an annotation