您必须区分 Java 8 类型注释 和(自 Java 5 起)参数 注释。关于类型注解的关键在于,您必须明确声明将注解用作类型注解的可能性。
考虑以下示例:
public class AnnoTest {
@Retention(RetentionPolicy.RUNTIME)
@interface Email {}
void example(@Email String arg) {}
public static void main(String[] args) throws ReflectiveOperationException {
Method method=AnnoTest.class.getDeclaredMethod("example", String.class);
System.out.println("parameter type annotations:");
AnnotatedType annotatedType = method.getAnnotatedParameterTypes()[0];
//Annotation annotation = annotatedType.getAnnotation(Annotation.class);
System.out.println(Arrays.toString(annotatedType.getAnnotations()));
System.out.println("parameter annotations:");
System.out.println(Arrays.toString(method.getParameterAnnotations()[0]));
}
}
它会打印出来
parameter type annotations:
[]
parameter annotations:
[@AnnoTest$Email()]
在这种情况下,注解是参数的一个属性。
现在将其更改为(注意@Target)
public class AnnoTest {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface Email {}
void example(@Email String arg) {}
public static void main(String[] args) throws ReflectiveOperationException {
Method method=AnnoTest.class.getDeclaredMethod("example", String.class);
System.out.println("parameter type annotations:");
AnnotatedType annotatedType = method.getAnnotatedParameterTypes()[0];
//Annotation annotation = annotatedType.getAnnotation(Annotation.class);
System.out.println(Arrays.toString(annotatedType.getAnnotations()));
System.out.println("parameter annotations:");
System.out.println(Arrays.toString(method.getParameterAnnotations()[0]));
}
}
将打印出来
parameter type annotations:
[@AnnoTest$Email()]
parameter annotations:
[]
相反。所以现在,注解是参数type的一个特征,即String。从概念上讲,该方法的参数类型现在是@Email String(这似乎是最合乎逻辑的选择,因为它允许声明像List<@Email String> 这样的类型,但是您必须了解这些新类型注释是如何工作的并且它不起作用以及 Java 8 之前的库)。
为参数和类型使用启用注释时必须小心,因为这可能会产生模棱两可的注释。
如果发生这种情况,编译器将记录参数和类型的注释,例如
当您将示例中的目标更改为@Target({ElementType.TYPE_USE, ElementType.PARAMETER})时,它将打印
parameter type annotations:
[@AnnoTest$Email()]
parameter annotations:
[@AnnoTest$Email()]
类似的问题可能会出现在方法返回类型,resp。启用“类型使用”和方法的注释时的字段类型,resp。字段。