JavaWeb学习-注解-3-反射注解

痛定思痛。 2024-04-17 05:55 112阅读 0赞

这篇来学习反射注解,前面我们知道如果需要使用反射,那么注解的保留策略一定要是RUNTIME类型。本篇来学习下如何通过反射获取作用在不同目标上的注解内容。

反射注解需要从作用目标上返回

  • 类上的注解,需要从Class来获取
  • 方法上的注解,需要从Method来获取
  • 构造器上注解,需要从Construcation来获取
  • 成员上注解,需要从Field上获取

根据前面学的,其实还有其他注解的作用目标,这里我们就看这四个来学习反射注解。上面四个类,Class类单独分一类,后面三个分一类。通过JDK查看后面三个类,都在reflect,反射包下,有一个共同父类AccessibleObject。

反射注解练习

这里来一个练习,先定义一个注解,然后看看反射注解。

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @interface MyAnnotation{
  3. String name();
  4. int age();
  5. String gender();
  6. }

获取作用目标为类上注解信息

  1. package annotation;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. public class Demo1 {
  5. }
  6. @MyAnnotation(name="A类", age=18, gender="男")
  7. class A{
  8. @MyAnnotation(name="fun1方法", age=19, gender="女")
  9. public void fun1() {
  10. }
  11. }
  12. @Retention(RetentionPolicy.RUNTIME)
  13. @interface MyAnnotation{
  14. String name();
  15. int age();
  16. String gender();
  17. }

先准备这段代码,我们在A类上和A类的方法中都使用了注解,那么如何获取A类上的注解信息,也就是如何通过代码拿到name=”A类”, age=18, gender=”男” 这个信息。

  1. package annotation;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import org.junit.Test;
  5. public class Demo1 {
  6. @Test
  7. public void fun1() {
  8. // 1. 得到作用目标
  9. Class<A> c = A.class;
  10. // 2.获取指定类型的注解,当前我们这里类型就一个 MyAnnotation
  11. MyAnnotation myAn = c.getAnnotation(MyAnnotation.class);
  12. System.out.println(myAn.name() + ", " + myAn.age() + ", " + myAn.gender());
  13. }
  14. }
  15. @MyAnnotation(name="A类", age=18, gender="男")
  16. class A{
  17. @MyAnnotation(name="fun1方法", age=19, gender="女")
  18. public void fun1() {
  19. }
  20. }
  21. @Retention(RetentionPolicy.RUNTIME)
  22. @interface MyAnnotation{
  23. String name();
  24. int age();
  25. String gender();
  26. }

运行输出结果是

A类, 18, 男

获取作用目标为方法上注解信息

下面代码来获取A类下的方法fun1()上的注解内容。

  1. package annotation;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.reflect.Method;
  5. import org.junit.Test;
  6. public class Demo1 {
  7. @Test
  8. public void fun1() throws ReflectiveOperationException, SecurityException {
  9. // 1. 得到作用目标, 这时候是方法
  10. Class<A> c = A.class;
  11. Method method = c.getMethod("fun1");
  12. // 2.获取指定类型的注解,当前我们这里类型就一个 MyAnnotation
  13. MyAnnotation myAn = method.getAnnotation(MyAnnotation.class);
  14. System.out.println(myAn.name() + ", " + myAn.age() + ", " + myAn.gender());
  15. }
  16. }
  17. @MyAnnotation(name="A类", age=18, gender="男")
  18. class A{
  19. @MyAnnotation(name="fun1方法", age=19, gender="女")
  20. public void fun1() {
  21. }
  22. }
  23. @Retention(RetentionPolicy.RUNTIME)
  24. @interface MyAnnotation{
  25. String name();
  26. int age();
  27. String gender();
  28. }

输出内容

fun1方法, 19, 女

获取构造器上注解信息

有了前面两个获取的基础,获取构造器就简单了,直接来看下面代码。

  1. package annotation;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.reflect.Constructor;
  5. import java.lang.reflect.Method;
  6. import org.junit.Test;
  7. public class Demo1 {
  8. @Test
  9. public void fun1() throws ReflectiveOperationException, SecurityException {
  10. // 1. 得到作用目标,
  11. Class<A> c = A.class;
  12. Constructor constructor = c.getConstructor(); // 这种我们没写带参数的构造,参数为空
  13. // 2.获取指定类型的注解,当前我们这里类型就一个 MyAnnotation
  14. MyAnnotation myAn = (MyAnnotation) constructor.getAnnotation(MyAnnotation.class);
  15. System.out.println(myAn.name() + ", " + myAn.age() + ", " + myAn.gender());
  16. }
  17. }
  18. @MyAnnotation(name="A类", age=18, gender="男")
  19. class A{
  20. // 构造器
  21. @MyAnnotation(name="构造器", age=20, gender="不清楚")
  22. public A() {
  23. }
  24. @MyAnnotation(name="fun1方法", age=19, gender="女")
  25. public void fun1() {
  26. }
  27. }
  28. @Retention(RetentionPolicy.RUNTIME)
  29. @interface MyAnnotation{
  30. String name();
  31. int age();
  32. String gender();
  33. }

输出结果

构造器, 20, 不清楚

从输出结果来看,我们正确地得到了该作用目标的注解内容,下面来直接看字段注解如何获取。

  1. package annotation;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.reflect.Field;
  5. import org.junit.Test;
  6. public class Demo1 {
  7. @Test
  8. public void fun1() throws ReflectiveOperationException, SecurityException {
  9. // 1. 得到作用目标,
  10. Class<A> c = A.class;
  11. Field field = c.getField("userName");
  12. // 2.获取指定类型的注解,当前我们这里类型就一个 MyAnnotation
  13. MyAnnotation myAn = field.getAnnotation(MyAnnotation.class);
  14. System.out.println(myAn.name() + ", " + myAn.age() + ", " + myAn.gender());
  15. }
  16. }
  17. @MyAnnotation(name="A类", age=18, gender="男")
  18. class A{
  19. @MyAnnotation(name="成员变量", age=23, gender="男")
  20. public String userName;
  21. // 构造器
  22. @MyAnnotation(name="构造器", age=20, gender="不清楚")
  23. public A() {
  24. }
  25. @MyAnnotation(name="fun1方法", age=19, gender="女")
  26. public void fun1() {
  27. }
  28. }
  29. @Retention(RetentionPolicy.RUNTIME)
  30. @interface MyAnnotation{
  31. String name();
  32. int age();
  33. String gender();
  34. }

输出结果

成员变量, 23, 男

这里提醒一下,为什么要在A类的成员变量写成public,如果你写成了private,那么就变成不可访问。打开Class的JDK文档,找到getField()方法,明确说了“返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段”。

发表评论

表情:
评论列表 (有 0 条评论,112人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JavaWeb 注解

    java中有很多注解 按运行机制分 源码注解 只在源码中存在 编译时注解 在class中依然存在,如@Deprecated 运行时注解 运行阶段起作用,如

    相关 反射&注解

    今日目标 1. 获得字节码对象的三种方式 2. 能够使用反射操作构造方法,变量,方法 3. 能够获取自定义注解的变量值 4. 能够自定义注解 1.反射 1.