我正在使用Groovy进行编码,并且遇到了Java 8 @Repeatable元注释的问题。我认为我做的一切都是正确的,但似乎Groovy并没有认识到@Repeatable。这是我的示例代码;我希望两个注释中的信息都存储在MyAnnotationArray中:
import java.lang.annotation.*
class MyClass
{
@MyAnnotation(value = "val1")
@MyAnnotation(value = "val2")
void annotatedMethod()
{
println("annotated method called")
}
public static void main(String... args)
{
MyClass ob = new MyClass()
ob.annotatedMethod()
java.lang.reflect.Method m = ob.getClass().getMethod("annotatedMethod")
List annos = m.getAnnotations()
println("annos = $annos")
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyAnnotationArray)
public @interface MyAnnotation
{
String value() default "val0";
}
public @interface MyAnnotationArray
{
MyAnnotation[] MyAnnotationArray()
}
我发生了这样的错误:
Caught: java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface MyAnnotation: @MyAnnotation(value=val2)
java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface MyAnnotation: @MyAnnotation(value=val2)
如果我省略@Repeatable元注释,这正是我得到的。
如果我遗漏了一个重复的MyAnnotations,代码工作正常;然后没有错误,然后我可以按预期读取注释值。
Groovy可能不支持@Repeatable元注释吗?虽然this page提示可能是这种情况,但我找不到任何直截了当的文件(向下滚动到第88项)。
答案 0 :(得分:2)
我使用了java 1.8
和groovy 2.4.11
编译完成后,编译和解压缩相同的代码:
的java:
@MyAnnotationArray({@MyAnnotation("val1"), @MyAnnotation("val2")})
public void annotatedMethod()
{
System.out.println("annotated method called");
}
常规:
@MyAnnotation("val1")
@MyAnnotation("val2")
public void annotatedMethod()
{
System.out.println("annotated method called");null;
}
所以,在groovy中使用
作为解决方法//note the square brackets
@MyAnnotationArray( [@MyAnnotation("val1"), @MyAnnotation("val2")] )
public void annotatedMethod()
{
System.out.println("annotated method called");
}
完整脚本(因为注释声明中存在一些错误)
import java.lang.annotation.*
class MyClass
{
//@MyAnnotation(value = "val1")
//@MyAnnotation(value = "val2")
@MyAnnotationArray( [@MyAnnotation("val1"), @MyAnnotation("val2")] )
public void annotatedMethod()
{
System.out.println("annotated method called");
}
public static void main(String... args)
{
MyClass ob = new MyClass()
ob.annotatedMethod()
java.lang.reflect.Method m = ob.getClass().getMethod("annotatedMethod")
List annos = m.getAnnotations()
println("annos = $annos")
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(MyAnnotationArray)
public @interface MyAnnotation
{
String value() default "val0";
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotationArray
{
MyAnnotation[] value()
}
也针对groovy 3.0.0-SNAPSHOT
进行了尝试 - 结果与2.4.11
答案 1 :(得分:1)
是的,Groovy支持"可重复"只要保留策略只是SOURCE,即使在Java 5中也需要很长时间的注释。这是允许多个@Grab语句而没有外部@Grapes容器注释的原因。仅保留在SOURCE中使它们对AST转换和Groovy编译器本身(以及其他源处理器)有用,但在其他任何地方都没有用。我们目前根本不支持@Repeatable,但计划在将来的版本中使用。