[英]Annotation of multiple types of annotation
我希望能够使用在功能上相关但在参数上完全不同的2种类型的注释列表来对类进行注释。 但是,此列表的顺序很重要。 我已经尝试过查找此内容,但是无法找到对此的任何引用(我不确定该怎么称呼)。
编辑:
我最终想要做的是:
//place holder for example (Abstract)
public @interface A {
}
@Target(PARAMETER)
public @interface B extends A {
//Gets stuff
Class type();
int key();
}
@Target(PARAMETER)
public @interface FlaggedListOfA extends A {
//List of A
A[] set();
}
//Goal is to have annotation that does this
@Target(METHOD)
public @interface ImportantFunc {
A[] dataForA() default {};
String[] names();
int property() default 0;
//etc.
}
//End goal:
public class SomeImportantClass {
@ImportantFunc(dataForA = {@B(...), @B(...}, ...)
public void doStuff() {
}
//So I can have an end goal of this (Order matters, may contain repeats,
//and has unknown length!)
@ImportantFunc(dataForA = {@B(...), @FlaggedListOfA(@B(...), @B(...))}, ...)
public void doStuffB() {
}
@ImportantFunc(dataForA = {@FlaggedListOfA(@B(...)), @FlaggedListOfA(@B(...), @B(...))}, ...)
public void doStuffC() {
}
@ImportantFunc(dataForA = {@FlaggedListOfA(@B(...), @FlaggedListOfA(@B(...), @B(...))), @B(...)}, ...)
public void doStuffD() {
}
}
在包中获得对ImportantFunc的所有使用(例如:100次使用)的反射,并使用此数据选择要使用的功能。 批注有助于反射,因为一旦它从@ImportantFunc获取数据,便会将其转换为库的输入,该库将实际选择要执行的函数(这是内部函数,不能修改)。 这也可以用更长,更烦人的方法来实现,但是我希望使用注释来简化定义所有这些功能的过程。
编辑:
可以解决的另一种方法是找到一种将两个注释分组在一起的方法。
能够做到这一点并不是完全理想的,但肯定会使它更可行:
public @interface Example {
AnyTypeOfAnnotation[] set();
}
一种行之有效的方法是使A
成为B
和C
并集。 这意味着它既有的各个领域B
和C
,但你永远只能用它无论是作为B
或 C
。
这是一个工作示例。
import java.lang.annotation.*;
enum NoType {;}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface A {
Class<?> data() default NoType.class; // field from B
int dataA() default 0; // field from C
String dataB() default ""; // field from C
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface D {
A[] value() default {};
}
class Foo {}
class Bar {}
class Example {
@D({
@A(data = Bar.class),
@A(dataA = 5, dataB = "Bla"),
@A(data = Foo.class)
})
public static void main(String[] args) throws Exception {
for (A a : Example.class.getMethod("main", String[].class)
.getAnnotation(D.class).value()) {
if (a.data() != NoType.class) {
System.out.printf("B(%s)%n", a.data());
} else {
System.out.printf("C(dataA = %d, dataB = \"%s\")%n",
a.dataA(), a.dataB());
}
}
}
}
B(class Bar)
C(dataA = 5, dataB = "Bla")
B(class Foo)
当然,这不是一个很好的解决方案,但确实可以。
不确定这对于您的用例是否足够:
public @interface A {
}
public @interface B extends A {
//Gets stuff
Class data();
}
public @interface C extends A {
//Gets different stuff related to same goal
int dataA();
String dataB();
}
public @interface D {
Class<? extends A>[] order();
}
@B(Bar.class)
@C(dataA = 5, dataB = "Bla")
@D(order = {B.class, C.class})
public class SomeImportantClass {
}
此方法使用D
注释作为保留注释顺序的手段。 不好的部分是您不能添加相同类型的多个注释。
还有另一种使A
, B
和C
成为普通类的方法。
public abstract class AnnotationAttribute {
public abstract Class<?>[] getDataTypes();
public abstract Object[] getData();
}
public class B extends AnnotationAttribute {
@Override public Class<?>[] getDataTypes() {
return new Class<?>[] {Foo.class, Bar.class};
}
@Override public Object[] getData() {
return new Object[] {new Foo(), new Bar()};
}
}
public @interface D {
Class<? extends AnnotationAttribute>[] data() default {};
}
@D(data = {B.class});
public class Test {
}
此方法要求您为一种具体的属性类型创建一个类。 这是因为注释必须是编译时常量,并且通过Class
引用需要您在代码中定义类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.