Guys有办法将Annotation作为直接参数传递(而不是通过执行所有反射开销)吗?例如,在下面的代码中,我有一个包含int值的注释Number,我想作为参数传递给addImpl方法,我该怎么做(除了通过反射)?
代码段:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
public @interface Number {
int value();
}
public void add(int x2) {
addImpl(@Number(value = 10) lol, x2);
}
public void addImpl(Number a, int b) {
System.out.println(a.value() + b);
}
public static void main(String[] args) {
new TestClass().add(3);
}
答案 0 :(得分:21)
是的,您可以传递这样的注释(就像它们是普通的接口一样)。
您唯一不能做的是在运行时创建该接口的实例。您只能使用现有注释并传递它们。
import java.lang.annotation.*;
public class Example {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public static @interface Number {
int value();
}
@Number(value = 42)
public int adder(final int b) throws SecurityException, NoSuchMethodException {
Number number = getClass().getMethod("adder", int.class).getAnnotation(Number.class);
return addImpl(number, b);
}
public int addImpl(final Number a, final int b) {
return a.value() + b;
}
public static void main(final String[] args) throws SecurityException, NoSuchMethodException {
System.out.println(new Example().adder(0));
}
}
答案 1 :(得分:9)
你可以这样做:
public void add(int x2) {
addImpl(new Number() {
@Override
public int value() {
return 10;
}
@Override
public Class<? extends Annotation> annotationType() {
return Number.class;
}
}, x2);
}
由于Number基本上是一个接口,因此您必须创建一个实现该接口的匿名类的实例,并将其传递给该方法。
虽然你想要这样做的原因超出了我的范围。如果你需要将值传递给某个东西,你应该真正使用一个类。
答案 2 :(得分:4)
据我所知,没有“注释文字”这样的东西,因为你想在add
实现中使用它。
我认为最接近于此的方法是声明方法采用类型java.lang.annotation.Annotation的参数 - 但是你仍然需要通过类/方法对象的反射来获取这些实例。
答案 3 :(得分:2)
Number也是一个很好的旧界面,你可以实现一个具体的类。
伙计们,这很有用。虽然模块主要处理在编译时修复的注释,但有时我们需要在运行时从其他源(例如xml,gush!)获取其他信息。我们可以过度构建事物,或者我们可以简单地创建运行时注释类型的对象。
答案 4 :(得分:2)
如果你需要在测试中传递注释,你可以模拟它。 例如,JSR 303验证器的测试可能如下所示:
public void test() {
final TextLengthValidator validator = new TextLengthValidator();
validator.initialize(mock(TextLength.class));
final boolean valid = validator.isValid("some text", mock(ConstraintValidatorContext.class));
assertThat(valid, is(true));
}