• 【反射】获取类、构造器、成员变量、成员方法以及作用和应用场景


    反射

    1.认识反射、获取类
    • 反射(Reflection):加载类,并允许以编程的方式,解剖类中各种成分(成员变量、方法、构造器等)

    • 获取Class对象的三种方式

      (1)Class对象阶段(已经加载到内存)->Class c1=类名.class

      (2)源码阶段(还没有加载到内存)->调用Class提供的方法:public static Class forName(String package)

      (3)Runtime运行阶段(手动new对象时)->Object提供的方法:public Class getClass(); Class c3=对象.getClass()

    public class Demo {
        public static void main(String[] args) throws ClassNotFoundException {
            //1、Class类的静态方法forName(String 全限定名);
            Class c1 = Class.forName("com.demo04_reflect_获取类.Student");//全类名=包名+类名
            System.out.println(c1.getName()); //com.demo04_reflect_获取类.Student
            System.out.println(c1.getSimpleName()); //Student
    
            //2、类名.class
            Class c2 = Student.class;
            System.out.println(c2.getName());
            System.out.println(c2.getSimpleName());
    
            //3、对象.getClass()
            Student stu = new Student("张三", 18);
            Class c3 = stu.getClass();
            System.out.println(c3.getName());
            System.out.println(c3.getSimpleName());
    
            //这三个Class对象是不是一个对象?
            System.out.println(c1 == c2);//true
            System.out.println(c2 == c3);//true
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    2.获取类的构造器
    • Class提供了从类中获取构造器的方法

      方法说明
      Constructor[] getConstructors()获取全部构造器(只能获取public修饰的)
      Constructor[] getDeclaredConstructors()获取全部构造器(只要存在就能拿到)
      Constructor< T >[] getConstructors(Class… parameterTypes)获取某个构造器(只能获取public修饰的)
      Constructor< T >[] getDeclaredConstructors(Class… parameterTypes)获取某个构造器(只要存在就能拿到)
    • 获取类构造器的作用:依然是初始化对象返回

      Constructor提供的方法说明
      T newInstance(Object…initargs)调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回
      public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)

      实体类Cat:

      public class Cat {
          //公共空参
          public Cat() {
          }
      
          //公共带参
          public Cat(String name, int age) {
          }
      
          //私有带参
          private Cat(String name) {
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13

      测试类:

      public class Demo {
          @Test
          public void testGetDeclaredConstructor() throws NoSuchMethodException {
              //加载类
              Class clazz = Cat.class;
              //获取单个指定的(只要存在,包含私有
              Constructor c1 = clazz.getDeclaredConstructor(String.class);
              System.out.println(c1); //private com.demo05_reflect_获取构造器对象.Cat(java.lang.String)
          }
      
          @Test
          public void testGetConstructor() throws NoSuchMethodException {
              Class clazz = Cat.class;
              //获取单个指定的(公共的)
              Constructor c1 = clazz.getConstructor();
              System.out.println(c1); //public com.demo05_reflect_获取构造器对象.Cat()
              Constructor c2 = clazz.getConstructor(String.class, int.class);
              System.out.println(c2); //public com.demo05_reflect_获取构造器对象.Cat(java.lang.String,int)
          }
      
          @Test
          public void testGetDeclaredConstructors() {
              Class clazz = Cat.class;
              //Constructor[] getDeclaredConstructors(); 获取所有(只要存在,包含私有的)
              Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
              //遍历数组
              for (Constructor declaredConstructor : declaredConstructors) {
                  System.out.println(declaredConstructor);
                  /*
                      public com.demo05_reflect_获取构造器对象.Cat()
                      public com.demo05_reflect_获取构造器对象.Cat(java.lang.String,int)
                      private com.demo05_reflect_获取构造器对象.Cat(java.lang.String)
                   */
              }
          }
      
          @Test
          public void testGetConstructors() {
              Class clazz = Cat.class;
              //Constructor[] getConstructors(); 获取所有(公共的)
              Constructor[] constructors = clazz.getConstructors();
              //遍历数组
              for (Constructor constructor : constructors) {
                  System.out.println(constructor);
                  /*
                      public com.demo05_reflect_获取构造器对象.Cat()
                      public com.demo05_reflect_获取构造器对象.Cat(java.lang.String,int)
                   */
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51

      通过构造器实例化对象

      实体类Cat:

      public class Cat {
          private String name;
          private int age;
      
          //私有空参
          private Cat() {
              System.out.println("私有空参执行了...");
          }
      
          //公共带参
          public Cat(String name, int age) {
              System.out.println("公共带参执行了...");
              this.name = name;
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Cat{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24

      测试类:

      public class Demo {
          @Test //通过公共带参,创建对象
          public void testNewInstance2() throws Exception {
              //加载类
              Class clazz = Cat.class;
              //获取公共的带构造
              Constructor constructor = clazz.getConstructor(String.class, int.class);
              //T newInstance(参数1,参数2..); 通过构造器对象和指定参数,创建对象并返回(可强转为具体类型)
              Cat cat = (Cat) constructor.newInstance("大橘", 5);
              System.out.println(cat); //Cat{name='大橘', age=5}
          }
      
          @Test //通过私有空参,创建对象
          public void testNewInstance1() throws Exception {
              //加载类
              Class clazz = Cat.class;
              //获取私有的空参构造
              Constructor constructor = clazz.getDeclaredConstructor();
              //public void setAccessible(boolean flag); 参数为true表示禁止检查访问控制(暴力反射)
              constructor.setAccessible(true); //禁止检查
              //T newInstance(参数1,参数2..); 通过构造器对象和指定参数,创建对象并返回(可强转为具体类型)
              Cat c = (Cat) constructor.newInstance();
              System.out.println(c); //Cat{name='null', age=0}
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
    3.获取类的成员变量
    • Class提供了从类中获取成员变量的方法

      方法说明
      public Filed[] getFileds()获取类的全部成员变量(只能获取public修饰的)
      public Filed[] getDeclaredFileds()获取类的全部成员变量(只要存在就能拿到)
      public Filed getFiled(String name)获取类的某个成员变量(只能获取public修饰的)
      public Filed[] getDeclaredFiled(String name)获取类的某个成员变量(只要存在就能拿到)
    • 获取到成员变量的作用:依然是赋值、取值

      方法说明
      void set(Object obj,Object value)赋值
      Object get(Object obj)取值
      public void seAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)
      class Cat {
          public static int number;
          public static final String COUNTRY = "中国";
          private String name;
          private int age;
      
          public Cat() {
      
          }
      
          public Cat(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Cat{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
      public class Demo {
          //给成员变量赋值和取值
          @Test
          public void testGetAndSet() throws Exception {
              Class clazz = Cat.class;
              Field field = clazz.getDeclaredField("name");
              field.setAccessible(true);
              Cat c = new Cat();
              String name = (String)field.get(c);
              //System.out.println(name);
              field.set(c,"daju");
              String name1=(String)field.get(c);
              System.out.println(name1);
      
          }
      
          @Test
          public void testGetDeclaredField() throws NoSuchFieldException {
              Class clazz = Cat.class;
              System.out.println(clazz.getDeclaredField("name"));
      
          }
      
          @Test
          public void testGetField() throws NoSuchFieldException {
              Class clazz = Cat.class;
              System.out.println(clazz.getField("number"));
      
      
          }
      
          @Test
          public void testGetDeclaredFields() {
              Class clazz = Cat.class;
              Field[] declaredFields = clazz.getDeclaredFields();
              for (Field declaredField : declaredFields) {
                  System.out.println(declaredField);
      
              }
      
          }
      
          @Test
          public void testGetFields() {
              Class clazz = Cat.class;
              Field[] fields = clazz.getFields();
              for (Field field : fields) {
                  System.out.println(field);
      
              }
      
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
    4.获取类的成员方法
    • Class提供了从类中获取成员方法的API

      方法说明
      Method[] getMethods()获取类的全部成员方法(只能获取public修饰的)
      Method getDeclaredMethods()获取类的全部成员方法(只要存在就能拿到)
      Method getMethod(String name,Class…parameterTypes)获取类的某个成员方法(只能获取public修饰的)
      Method getDeclaredMethod(String name,Class…parameterTypes)获取类的某个成员方法(只要存在就能拿到)
    • 成员方法的作用:依然是执行

      Method提供的方法说明
      public Object invoke(Object obj,Object…args)触发某个对象的方法执行
      public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)
    class Cat {
        private String name;
        private int age;
    
        public Cat() {
    
        }
    
        public Cat(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        //公共,无参无返
        public void play() {
            System.out.println("小猫捉迷藏");
        }
    
        //私有,有参有返
        private String eat(String food) {
            return "小猫爱吃" + food;
        }
    
        //公共,无参有返
        @Override
        public String toString() {
            return "Cat{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    public class Demo {
    
        @Test
        public void testGetDeclaredMethod() throws Exception {
            Class clazz = Cat.class;
            Method declaredMethod = clazz.getDeclaredMethod("eat", String.class);
            Cat c = (Cat)clazz.newInstance();
            declaredMethod.setAccessible(true);
            Object invoke = declaredMethod.invoke(c, "maotiao");
            System.out.println(invoke);
    
    
        }
    
        @Test
        public void testGetMethod() throws Exception{
            Class clazz = Cat.class;
            Method method = clazz.getMethod("play");
            Cat c = (Cat) clazz.newInstance();
            method.invoke(c);
    
        }
    
        @Test
        public void testGetDeclaredMethods() throws Exception {
            Class clazz = Cat.class;
            Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                System.out.println(declaredMethod.getName());
    
            }
    
        }
    
        @Test
        public void testGetMethods() {
            Class clazz = Cat.class;
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                System.out.println(method.getName());
    
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    5.作用、应用场景
    • 基本作用:可以得到一个类的全部成分然后操作
    • 可以破坏封装性
    • 最重要的用途:适合做Java的框架,基本上主流的框架都会基于反射设计出一些通用的功能
  • 相关阅读:
    永远无法实现的“诚实“
    基于DF模式的协作通信技术matlab性能仿真
    Clearview X for mac v3.5.0 电子书阅读器 兼容 M1/M2/M3
    【Azure APIM】APIM 策略语句如何来设置多个Cookie值让浏览器保存
    【微电网优化】基于matlab萤火虫算法求解微电网优化问题【含Matlab源码 2146期】
    ubuntu-hadoop伪分布
    QQ怎么上传大于1G的视频啊?视频压缩这样做
    8、MySQL——数据的完整性
    数据库缓存服务——NoSQL之Redis配置与优化
    Pandas 数据中的loc与iloc含义以及操作
  • 原文地址:https://blog.csdn.net/m0_65462447/article/details/133556750