包含其他注释的注释成员?
我想创建一个自定义注释(使用Java),它将接受其他注释作为参数,如:
public @interface ExclusiveOr { Annotation[] value(); }
但这会导致编译器错误“注释成员的无效类型”。
对象[]也不起作用。
有办法做我想要的吗?
产生错误是因为您不能将接口用作注释值(将其更改为Comparable
并且您将获得相同的错误)。 来自JLS :
如果在注释类型中声明的方法的返回类型是除以下之一之外的任何类型,则是编译时错误:其中一种基本类型,
String
,Class
和Class
任何调用,枚举类型,注释类型,或前面类型之一的数组。 如果在注释类型中声明的任何方法具有覆盖等同于在类Object
或接口annotation.Annotation
声明的任何public
或protected
方法的签名,则它也是编译时错误。
我担心我不知道一个好的解决方法,但现在至少你知道为什么你会得到错误。
我自己特此提出针对给定问题的解决方法:
好吧,我想让它成为可能的是这样的:
@Contract({ @ExclusiveOr({ @IsType(IAtomicType.class), @Or({ @IsType(IListType.class), @IsType(ISetType.class) }) }) })
建议的解决方法:
使用无参数构造函数(稍后将由您自己的注释处理器调用)以下列方式定义一个类:
final class MyContract extends Contract{ // parameter-less ctor will be handeled by annotation processor public MyContract(){ super( new ExclusiveOr( new IsType(IAtomicType.class), new Or( new IsType(IListType.class), new IsType(ISetType.class) ) ) ); } }
用法:
@Contract(MyContract.class) class MyClass{ // ... }
根据您希望指定其他注释的原因,有多种解决方案:
单个注释类型的实例数组
可能不是你在你的问题中的意思,但如果你想指定单个注释类型的多个实例,它肯定是可能的:
public @interface Test { SomeAnnotation[] value(); }
一组注释类型而不是实例
如果您不需要在单个注释上指定任何参数,则只需使用其类对象而不是实例。
public @interface Test { Class extends Annotation>[] value(); }
但是在大多数情况下,枚举当然也会成功。
使用多个数组
如果要使用的可能注释类型集受限,则可以为每个注释类型创建单独的参数。
public @interface Test { SomeAnnotation[] somes() default { }; ThisAnnotation[] thiss() default { }; ThatAnnotation[] thats() default { }; }
为每个成员提供默认值使得只能为所需类型指定数组。
你可以做:
Class extends Annotation>[] value();
不确定这是否有帮助,但是。 。 。
我刚刚遇到了这个确切的问题,但是(受@ivan_ivanovich_ivanoff启发)我发现了一种方法来指定任何 Annotations组合作为注释成员的包:使用原型/模板类。
在这个例子中,我定义了一个WhereOr (即我的模型注释的“where子句”),我需要包含任意Spring元注释(如@Qualifier元注释)。
这里的次要(?)缺陷是强制解除引用,它将where子句的实现与它描述的具体类型分开。
@Target({}) @Retention(RetentionPolicy.RUNTIME) public @interface WhereOr { Class>[] value() default {}; } @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface JsonModel { Class> value(); WhereOr where() default @WhereOr; } public class Prototypes { @Qualifier("myContext") @PreAuthorize("hasRole('ROLE_ADMINISTRATOR')") public static class ExampleAnd { } } @JsonModel( value = MusicLibrary.class, where = @WhereOr(Prototypes.ExampleAnd.class) ) public interface JsonMusicLibrary { @JsonIgnore int getMajorVersion(); // ... }
我将以编程方式从“where子句”注释中提取可能的有效配置。 在这种情况下,我还使用prototypes类作为逻辑AND分组,并将类数组用作逻辑OR。