我希望能够使用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() {
}
}
答案 0 :(得分:1)
一种灵活的方法是使A
成为B
和C
的并集。这意味着它具有 both B
和C
的所有字段,但是您只能将它用作或和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());
}
}
}
}
B(class Bar)
C(dataA = 5, dataB = "Bla")
B(class Foo)
当然,这不是一个非常漂亮的解决方案,但是它确实有效。
答案 1 :(得分:0)
不确定这对于您的用例是否足够:
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
此方法要求您为一种具体的属性类型创建一个类。这是因为注释必须是编译时常量,并且通过SET
进行引用需要您在代码中定义类。