现在我们通过反射来获取类注解上的信息,代码实现如下:
package demo.annotation; import java.lang.annotation.Annotation; public class AnnotationParse { //解析类上面的注解 public static void parseTypeAnnotation() throws ClassNotFoundException { Class<?> clazz = Class.forName("demo.annotation.SelfStudyCourse"); // 这里获取的是class对象的注解,而不是其里面的方法和成员变量的注解 Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { CourseInfoAnnotation courseInfoAnnotation = (CourseInfoAnnotation) annotation; System.out.println("课程名: " +courseInfoAnnotation.courseName() + "\n" + "课程标签: " + courseInfoAnnotation.courseTag() + "\n" + "课程简介: "+ courseInfoAnnotation.courseProfile() + "\n" + "课程代号: " + courseInfoAnnotation.courseIndex()); } } public static void main(String[] args) throws ClassNotFoundException { parseTypeAnnotation(); } } /** * 程序运行结果如下: * 课程名: 计算机网络 * 课程标签: 计算机基础 * 课程简介: 计算机网络学习的核心内容就是网络协议的学习。网络协议是为计算机网络中进行数据交换而建立的规则、标准或者说是约定的集合。因为不同用户的数据终端可能采取的字符集是不同的,两者需要进行通信,必须要在一定的标准上进行 * 课程代号: 107 */现在通过来反射来获取成员变量和方法上的注解信息
// 解析字段上的注解信息 public static void parseFieldAnnotation() throws ClassNotFoundException { Class<?> clazz = Class.forName("demo.annotation.SelfStudyCourse"); // 获取该对象的所有成员变量 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { // 判断成员变量中是否有指定注解类型的注解 boolean hasAnnotation = field.isAnnotationPresent(PersonInfoAnnotation.class); if (hasAnnotation) { PersonInfoAnnotation personInfoAnnotation = field.getAnnotation(PersonInfoAnnotation.class); System.out.println("名字: " + personInfoAnnotation.name() + "\n" + "年龄: " + personInfoAnnotation.age() + "\n" + "性别: " + personInfoAnnotation.gender()); for (String language : personInfoAnnotation.language()) { System.out.println("课程名: " + language); } } } } // 解析方法上的注解信息 public static void parseMethodAnnotation() throws ClassNotFoundException { Class<?> clazz = Class.forName("demo.annotation.SelfStudyCourse"); // 获取该对象的所有成员变量 Method[] methods = clazz.getMethods(); for (Method method : methods) { // 判断方法中是否有指定注解类型的注解 boolean hasAnnotation = method.isAnnotationPresent(CourseInfoAnnotation.class); if (hasAnnotation) { CourseInfoAnnotation methodAnnotation = method.getAnnotation(CourseInfoAnnotation.class); System.out.println("课程名: " +methodAnnotation.courseName() + "\n" + "课程标签: " + methodAnnotation.courseTag() + "\n" + "课程简介: "+ methodAnnotation.courseProfile() + "\n" + "课程代号: " + methodAnnotation.courseIndex()); } } }注解获取属性值的底层实现,是通过JVM为注解生成代理对象。
注解的工作原理通过键值对的形式为注解属性赋值
编译器检查注解的使用范围,将注解信息写入元素属性表,
运行时JVM将RUNTIME的所有注解属性取出并最终存入map里
创建AnnotationInvocationHandler实例并传入前面的map中
JVM使用JDK动态代理为注解生成代理类,并初始化对应的处理器(AnnotationInvocationHandler)
调用invoke方法,通过传入方法名返回注解对应的属性值