24.Java 新特性扩展(重复注解、类型注解)
一、重复注解
1、基本介绍
-
自从 JDK 5 引入注解以来,注解的使用开始流行,在各个框架中被广泛使用
-
不过注解有一个很大的限制,在同一个地方不能多次使用同一个注解
-
JDK 8 引入了重复注解的概念
2、具体实现
(1)自定义注解
- MyAnnotation 注解
package com.my.repeatannotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
// 指定对应的容器
@Repeatable(MyAnnotations.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
- MyAnnotations 注解(重复注解的容器)
package com.my.repeatannotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations {
MyAnnotation[] value();
}
(2)实体类
- MyUser 类
package com.my.repeatannotation;
@MyAnnotation("a1")
@MyAnnotation("a2")
@MyAnnotation("a3")
public class MyUser {
@MyAnnotation("b1")
@MyAnnotation("b2")
@MyAnnotation("b3")
private String name;
@MyAnnotation("c1")
@MyAnnotation("c2")
@MyAnnotation("c3")
public void say() {};
}
(3)测试
- RepeatAnnotationTest 类
package com.my.repeatannotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class RepeatAnnotationTest {
public static void main(String[] args) {
Class<MyUser> myUserClass = MyUser.class;
// 获取类的重复注解
MyAnnotation[] myAnnotations1 = myUserClass.getAnnotationsByType(MyAnnotation.class);
for (MyAnnotation myAnnotation : myAnnotations1) {
System.out.println(myAnnotation.value());
}
// 获取属性的重复注解
Field[] declaredFields = myUserClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
MyAnnotation[] myAnnotations2 = declaredField.getAnnotationsByType(MyAnnotation.class);
for (MyAnnotation myAnnotation : myAnnotations2) {
System.out.println(myAnnotation.value());
}
}
// 获取方法的重复注解
Method[] declaredMethods = myUserClass.getDeclaredMethods();
for (Field declaredField : declaredFields) {
MyAnnotation[] myAnnotations3 = declaredField.getAnnotationsByType(MyAnnotation.class);
for (MyAnnotation myAnnotation : myAnnotations3) {
System.out.println(myAnnotation.value());
}
}
}
}
二、类型注解
1、基本介绍
-
JDK 8 中为 @Target 添加了两种类型
-
ElementType.TYPE_PARAMETER:表示该注解可以写在参数列表的数据类型或泛型的声明语句中
-
ElementType.TYPE_USE:表示该注解可以写在任何数据类型的声明语句中
-
2、具体实现
(1)自定义注解
- MyType 注解
package com.my.typeannotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyType {
String value();
}
(2)实体类
- MyStudent 类
package com.my.typeannotation;
import java.time.Instant;
public class MyStudent {
private @MyType("hello1") String name;
private @MyType("Hello2") Instant age;
public @MyType("Hello3") String say() {
return "Hello World";
};
public String eat(@MyType("Hello4") String food) {
return "Hello World";
}
}
(3)测试
- TypeAnnotationTest 类
package com.my.typeannotation;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.TypeVariable;
public class TypeAnnotationTest {
public static void main(String[] args) {
Class<MyStudent> myStudentClass = MyStudent.class;
TypeVariable<Class<MyStudent>>[] typeParameters = myStudentClass.getTypeParameters();
for (TypeVariable<Class<MyStudent>> typeParameter : typeParameters) {
// 获取类中泛型中的注解
MyType myType = typeParameter.getAnnotation(MyType.class);
System.out.println(myType.value());
}
Field[] declaredFields = myStudentClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
// 获取属性的数据类型的注解
AnnotatedType annotatedType = declaredField.getAnnotatedType();
MyType myType = annotatedType.getAnnotation(MyType.class);
System.out.println(myType.value());
}
Method[] declaredMethods = myStudentClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if (declaredMethod.getName().equals("say")) {
// 获取方法返回值的注解
AnnotatedType annotatedReturnType = declaredMethod.getAnnotatedReturnType();
MyType myType = annotatedReturnType.getAnnotation(MyType.class);
System.out.println(myType.value());
} else if (declaredMethod.getName().equals("eat")) {
// 获取方法参数列表的注解
AnnotatedType[] annotatedParameterTypes = declaredMethod.getAnnotatedParameterTypes();
MyType myType = annotatedParameterTypes[0].getAnnotation(MyType.class);
System.out.println(myType.value());
}
}
}
}