多种注释类型的注释

时间:2018-07-02 01:15:12

标签: java annotations

我希望能够使用2种类型的注释列表来注释一个类,这些注释在功能上相关,但参数却完全不同。但是,此列表的顺序很重要。我已经尝试过查找此内容,但是找不到任何对此的引用(我不确定该怎么称呼)。

编辑:

最后我想做什么:

  @foreach($registration->conference->registrationTypes as $registrationType)
    @foreach($registrationType->participants as $participant)
      <li>
          <div class="wrapper">
              <div class="conference-title">
                  <strong>Conference</strong><br> <span>{{ $registrationType->conference->name }}</span>
              </div>
              <div class="conference-regtype">
                  <div>
                      <strong>Registration Type </strong><br>
                      <span>{{ $registrationType->name }}</span>
                  </div>
              </div>  
              <div class="conference-participant">
                  <strong>Participant</strong><br>
                  <span>{{$participant->name}}</span>
              </div>
          </div>
      </li>
    @endforeach
  @endforeach

反映在包装中获得对ImportantFunc的所有使用(例如:100次使用),并使用此数据选择要使用的功能。批注有助于反射,因为一旦它从@ImportantFunc获取数据,便会将其转换为库的输入,该库将实际选择要执行的函数(这是内部函数,不能修改)。这也可以用更长,更烦人的方法来实现,但是我希望使用注释来简化定义所有这些功能的过程。

编辑:

可以解决的另一种方法是找到一种将两个注释分组在一起的方法。

能够做到这一点并不是完全理想的,但是肯定会使它更可行:

//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() {

    }
}

2 个答案:

答案 0 :(得分:1)

一种灵活的方法是使A成为BC的并集。这意味着它具有 both BC的所有字段,但是您只能将它用作B < em>或一个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());
            }
        }
    }
}

output of that program是:

B(class Bar)
C(dataA = 5, dataB = "Bla")
B(class Foo)

当然,这不是一个非常漂亮的解决方案,但是它确实有效。

答案 1 :(得分:0)

不确定这对于您的用例是否足够:

D

此方法使用A注释作为保留注释顺序的手段。糟糕的是,您不能添加相同类型的多个注释。

还有另一种方法可以将BCpublic 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

此方法要求您为一种具体的属性类型创建一个类。这是因为注释必须是编译时常量,并且通过SET进行引用需要您在代码中定义类。