我有一个注释,根据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模板。仍在寻找答案。
答案 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。