繁体   English   中英

多种注释类型的注释

[英]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成为BC并集。 这意味着它既有的各个领域BC ,但你永远只能用它无论是作为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注释作为保留注释顺序的手段。 不好的部分是您不能添加相同类型的多个注释。

还有另一种使ABC成为普通类的方法。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM