如何扩展Java注释?

bvi*_*iyg 29 java annotations

在我的项目中,我使用预定义的注释@With:

@With(Secure.class)
public class Test { //....
Run Code Online (Sandbox Code Playgroud)

源代码@With:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface With { 

    Class<?>[] value() default {};
}
Run Code Online (Sandbox Code Playgroud)

我想编写自定义注释@Secure,其效果与之相同@With(Secure.class).怎么做?


如果我这样喜欢怎么办?它会起作用吗?

@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {

}
Run Code Online (Sandbox Code Playgroud)

pio*_*rek 18

从Java语言规范,第9.6章注释类型:

不允许使用扩展条款.(注释类型隐式扩展annotation.Annotation.)

因此,您无法扩展Annotation.您需要使用其他一些机制或创建识别和处理您自己的注释的代码.Spring允许您在自己的自定义注释中对其他Spring的注释进行分组.但仍然没有扩展.

  • 对于任何想要使用 Spring 实现此目的的人来说,值得了解的是 Spring 的术语是“元注释”。“自定义注释”只是您自己定义的任何注释,并不一定意味着您使用第三方注释对其进行元注释。 (3认同)
  • 可能'延伸'并不是最好的表达方式.我的意思是为参数实现自动放置. (2认同)

小智 18

正如piotrek指出的那样,你不能在继承意义上扩展注释.您仍然可以创建聚合其他人的注释:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SuperAnnotation {
    String value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SubAnnotation {
    SuperAnnotation superAnnotation();
    String subValue();
}
Run Code Online (Sandbox Code Playgroud)

用法:

@SubAnnotation(subValue = "...", superAnnotation = @SuperAnnotation(value = "superValue"))
class someClass { ... }
Run Code Online (Sandbox Code Playgroud)

  • 因此,OP现在不必编写`@Secure(superAnnotation = @With(Secure.class))`,而不是编写@With(Secure.class)`?有什么帮助? (6认同)

Muh*_*man 6

@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {

}
Run Code Online (Sandbox Code Playgroud)

这会奏效.

  • @mkobit很好看.由于提问者询问这是否适用于他们的问题,我的答案直截了当,实际上回答了问题. (3认同)
  • 参见[Eric Jiang的回答](/sf/answers/3361985791/) (2认同)
  • 这是行不通的。我正在尝试为用 JPA 的“@Entity”注释的类上的字段创建自己的注释。我希望我的注释能够与“@Transient”以及其他内容执行相同的操作。 (2认同)

Eri*_*ang 5

为了扩展穆罕默德·阿卜杜勒拉赫曼的答案-

@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {

}
Run Code Online (Sandbox Code Playgroud)

这并不会在默认情况下工作,但你可以结合Spring的使用AnnotationUtils

有关示例,请参见此SO答案