Java高级-反射

目录

认识反射、获取类

反射(Reflection)

反射可进行的操作

加载类,获取类的字节码:Class对象

获取对象的三种方法

获取构造器对象并使用

获取构造器的方法

 获取构造器的作用

 获取成员变量和方法对象并使用

获取类的成员变量的方法

获取类的成员变量的作用

获取成员方法的方法

获取成员方法的作用


认识反射、获取类

反射(Reflection)

  • 反射就是:加载类,并允许以编程的方式剖析类中的各种成分(成员变量、方法、构造器等)

反射可进行的操作

加载类,获取类的字节码:Class对象
获取对象的三种方法
  • 反射第一步操作必须得到该类的Class对象
  • Class c1 = 类名.class
    • package com.example.Test;
      
      public class draft {
          public static void main(String[] args) {
              Class c1 = Student.class;
              // 打印输出全类名,即全限定名
              System.out.println(c1.getName());
              // 打印输出简类名,即类名
              System.out.println(c1.getSimpleName());
          }
      }
      
      class Student {
      
      };
    • 运行结果如下

      • Java高级-反射_第1张图片

  • 调用Class提供方法:public static Class forname(String package);
    • package com.example.Test;
      
      public class draft {
          public static void main(String[] args) throws Exception {
              Class c2 = Class.forName("com.example.Test.Student");
              System.out.println(c2.getName());
              System.out.println(c2.getSimpleName());
      
          }
      }
      
      class Student {
      
      };
    • 运行结果如下

      • Java高级-反射_第2张图片

  • Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();
    • package com.example.Test;
      
      public class draft {
          public static void main(String[] args) throws Exception {
              Student s = new Student();
              Class c = s.getClass();
              System.out.println(c.getName());
              System.out.println(c.getSimpleName());
      
          }
      }
      
      class Student {
      
      };
    • 运行结果如下

      • Java高级-反射_第3张图片


获取构造器对象并使用
获取构造器的方法
  • 构造器就是构造方法
  • 方法名 描述
    public Constructor getConstructor(Class... parameterTypes) 获取具有指定参数类型的公共(public修饰)构造器。
    public Constructor[] getConstructors() 获取所有公共(public修饰)构造器的数组。
    public Constructor getDeclaredConstructor(Class... parameterTypes) 获取具有指定参数类型的构造器,包括私有构造器。
    public Constructor[] getDeclaredConstructors() 获取所有构造器的数组,包括私有构造器。

     
  • 只演示一种
    • 具体代码如下
      • package com.example.Test;
        
        import org.junit.Test;
        
        import java.lang.reflect.Constructor;
        
        public class draft {
            @Test
            public static void main(String[] args) throws Exception {
                // 1. 反射第一步 获取该类的Class对象
                Class c = Student.class;
                // 2. todo 获取该类的全部构造器
                Constructor[] constructors = c.getConstructors();
                // 3.遍历数组中的构造器
                for (Constructor constructor : constructors) {
                    System.out.println(constructor.getName() + "参数个数为:" + constructor.getParameterCount());
                }
                System.out.println("----------------");
                // todo 根据参数类型获取构造器
                Constructor constructor1 = c.getConstructor(String.class, Integer.class);
                System.out.println(constructor1.getName() + "参数个数为:" + constructor1.getParameterCount());
        
            }
        }
        
        class Student {
            private String name;
            private Integer age;
        
            // todo 无参构造方法
            public Student() {
            }
        
            // todo 全参构造方法
            public Student(String name, Integer age) {
                this.name = name;
                this.age = age;
            }
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        
            public Integer getAge() {
                return age;
            }
        
            public void setAge(Integer age) {
                this.age = age;
            }
        };
    • 运行结果如下

      • Java高级-反射_第4张图片

 获取构造器的作用
  • 初始化对象返回
  • 构造器提供的方法
  • 方法名 描述
    public T newInstance(Object... initargs) 使用构造器创建一个新的对象实例。initargs参数是构造器的参数列表,用于传递初始化数据。该方法会调用构造器并返回新创建的对象实例。
    public void setAccessible(boolean flag) 设置构造器的可访问性。如果flag为true,则可以访问私有构造器(暴力反射);如果flag为false,则无法访问私有构造器。
  • 具体代码如下
    • package com.example.Test;
      
      import org.junit.Test;
      
      import java.lang.reflect.Constructor;
      
      public class draft {
          @Test
          public static void main(String[] args) throws Exception {
              // 1. 反射第一步 获取该类的Class对象
              Class c = Student.class;
              // todo 根据参数类型获取构造器
              Constructor constructor1 = c.getConstructor(String.class, Integer.class);
              System.out.println(constructor1.getName() + "参数个数为:" + constructor1.getParameterCount());
              Student s1 = (Student) constructor1.newInstance("hkm", 20); // todo 根据参数调用对应的构造器
              System.out.println(s1.toString());
              System.out.println("-------------------------------");
              Constructor constructor2 = c.getConstructor();
              System.out.println(constructor2.getName() + "参数个数为:" + constructor2.getParameterCount());
              Student s2 = (Student) constructor2.newInstance(); // todo 根据参数调用对应的构造器
              System.out.println(s2.toString());
      
          }
      }
      
      class Student {
          private String name;
          private Integer age;
      
          // todo 无参构造方法
          public Student() {
              System.out.println("无参构造器执行了~~");
          }
      
          // todo 全参构造方法
          public Student(String name, Integer age) {
              this.name = name;
              this.age = age;
              System.out.println("全参构造器执行了~~~");
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public Integer getAge() {
              return age;
          }
      
          public void setAge(Integer age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      };
  • 运行结果如下

    • Java高级-反射_第5张图片


 获取成员变量和方法对象并使用
  • 获取类的成员变量的方法
    • Class提供的从类中获取成员变量的方法
    • 方法名 描述
      public Field getField(String name) 根据成员变量的名称获取公共的成员变量。只能获取到公共的成员变量,不能获取到私有的成员变量。如果指定名称的成员变量不存在,或者指定名称的成员变量不是公共的,则会抛出NoSuchFieldException异常。
      public Field[] getFields() 获取所有公共(public修饰的)的成员变量。返回一个Field对象数组,包含了所有公共的成员变量。
      public Field getDeclaredField(String name) 根据成员变量的名称获取指定的成员变量,包括私有的成员变量。如果指定名称的成员变量不存在,或者指定名称的成员变量不是当前类的成员变量,则会抛出NoSuchFieldException异常。
      public Field[] getDeclaredFields() 获取所有的成员变量,包括公共的和私有的。返回一个Field对象数组,包含了所有的成员变量。
    • 具体代码
      • package com.example.Test;
        
        import org.junit.Test;
        
        import java.lang.reflect.Constructor;
        import java.lang.reflect.Field;
        
        public class draft {
            @Test
            public static void main(String[] args) throws Exception {
                // 1. 反射第一步 获取该类的Class对象
                Class c = Student.class;
                // todo 获取类中的全部成员变量
                Field[] fields = c.getDeclaredFields();
                for (Field field : fields) {
                    System.out.println(field.getName());
        
                }
                System.out.println("------------------");
                // todo 通过名称获取某个成员变量
                Field name = c.getDeclaredField("name");
                System.out.println(name.getName());
            }
        }
        
        class Student {
            private String name;
            private Integer age;
        
            // todo 无参构造方法
            public Student() {
                System.out.println("无参构造器执行了~~");
            }
        
            // todo 全参构造方法
            public Student(String name, Integer age) {
                this.name = name;
                this.age = age;
                System.out.println("全参构造器执行了~~~");
            }
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        
            public Integer getAge() {
                return age;
            }
        
            public void setAge(Integer age) {
                this.age = age;
            }
        
            @Override
            public String toString() {
                return "Student{" +
                        "name='" + name + '\'' +
                        ", age=" + age +
                        '}';
            }
        };
    • 运行结果

      • Java高级-反射_第6张图片
         

  • 获取类的成员变量的作用
    • 赋值、取值

    • 赋值取值的方法

      • 方法

        说明

        void set(Object obj,value) 赋值(为指定对象的成员变量赋值)
        void get(Object obj) 取值(取出指定对象的成员变量的值)
        public void setAccessiable(boolean flag) 设置为true,表示禁止访问控制(暴力反射
    • 具体代码如下

      • package com.example.Test;
        
        import org.junit.Test;
        
        import javax.swing.plaf.synth.SynthUI;
        import java.lang.reflect.Constructor;
        import java.lang.reflect.Field;
        
        public class draft {
            @Test
            public static void main(String[] args) throws Exception {
                // 1. 反射第一步 获取该类的Class对象
                Class c = Student.class;
                // todo 获取类中的全部成员变量
                Field[] fields = c.getDeclaredFields();
                for (Field field : fields) {
                    System.out.println(field.getName());
        
                }
                System.out.println("------------------");
                // todo 通过名称获取某个成员变量
                Field name = c.getDeclaredField("name");
        
                // todo 创建要赋值以及取值的类的对象
                Student student = new Student();
                name.set(student, "发老爷爷");
                System.out.println(student); // 赋值成功
                System.out.println(name.get(student));
        
                // todo 上述代码是对指定类Student中的name成员变量进行操作
        
                // todo 以下是对Student类中的age成员变量进行操作
                Field age = c.getDeclaredField("age");
                // 赋值
                age.set(student, 31);
                System.out.println(student);
                System.out.println(age.get(student));
                System.out.println("Student类中的age成员变量的赋值为"+ age.get(student));
            }
        }
        
        class Student {
            public String name;
            public Integer age;
        
            // todo 无参构造方法
            public Student() {
                System.out.println("无参构造器执行了~~");
            }
        
            // todo 全参构造方法
            public Student(String name, Integer age) {
                this.name = name;
                this.age = age;
                System.out.println("全参构造器执行了~~~");
            }
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        
            public Integer getAge() {
                return age;
            }
        
            public void setAge(Integer age) {
                this.age = age;
            }
        
            @Override
            public String toString() {
                return "Student{" +
                        "name='" + name + '\'' +
                        ", age=" + age +
                        '}';
            }
        };
    • 运行结果如下

      • Java高级-反射_第7张图片


获取成员方法的方法
  • 方法 说明
    getDeclaredMethods() 返回类中声明的所有方法,包括公共、保护、默认(包)访问和私有方法。
    getMethods() 返回类中所有公共方法,包括从父类继承的方法。
    getDeclaredMethod(String name, Class... parameterTypes) 返回类中指定名称和参数类型的方法。
    getMethod(String name, Class... parameterTypes) 返回类中指定名称和参数类型的公共方法,包括从父类继承的方法。
  • 具体代码如下
    • package com.example.Test;
      
      import org.junit.Test;
      
      import java.lang.reflect.Method;
      
      public class draft {
          @Test
          public static void main(String[] args) throws Exception {
              // 1. 反射第一步 获取该类的Class对象
              Class c = Student.class;
      //        todo 获取全部成员方法
              Method[] methods = c.getDeclaredMethods();
              for (Method method : methods) {
                  System.out.println(method.getName());
              }
              System.out.println("------------------------------------");
              // todo 获取某个成员方法
              Method student = c.getDeclaredMethod("run");
              System.out.println(student.getName());
          }
      
      }
      
      
      class Student {
          public String name;
          public Integer age;
      
          public void run() {
              System.out.println("run~~~~");
          }
      
          private void jump() {
              System.out.println("jump~~~");
          }
      
          // todo 无参构造方法
          public Student() {
              System.out.println("无参构造器执行了~~");
          }
      
          // todo 全参构造方法
          public Student(String name, Integer age) {
              this.name = name;
              this.age = age;
              System.out.println("全参构造器执行了~~~");
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public Integer getAge() {
              return age;
          }
      
          public void setAge(Integer age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      };

  • 运行结果如下
    • Java高级-反射_第8张图片
获取成员方法的作用
  • 依然是执行该方法
  • 方法 说明
    public Object invoke(Object obj,Object ...args) 触发某个对象的该方法执行
    public void setAccessible(boolean flag) 设置为true,表示禁止访问控制(暴力反射)
  • 具体代码如下
    • package com.example.Test;
      
      import org.junit.Test;
      
      import java.lang.reflect.Method;
      
      public class draft {
          @Test
          public static void main(String[] args) throws Exception {
              // 1. 反射第一步 获取该类的Class对象
              Class c = Student.class;
      //        todo 获取全部成员方法
              Method[] methods = c.getDeclaredMethods();
              for (Method method : methods) {
                  System.out.println(method.getName());
              }
              System.out.println("------------------------------------");
              // todo 获取某个成员方法
              Method run = c.getDeclaredMethod("run");
              Method jump = c.getDeclaredMethod("jump", String.class);
              jump.setAccessible(true);
              Student student = new Student();
              jump.invoke(student, "hkm");
              run.invoke(student);
      
          }
      
      }
      
      
      class Student {
          public String name;
          public Integer age;
      
          public void run() {
              System.out.println("run~~~~");
          }
      
          private void jump(String name) {
              System.out.println(name + ":jump~~~");
          }
      
          // todo 无参构造方法
          public Student() {
              System.out.println("无参构造器执行了~~");
          }
      
          // todo 全参构造方法
          public Student(String name, Integer age) {
              this.name = name;
              this.age = age;
              System.out.println("全参构造器执行了~~~");
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public Integer getAge() {
              return age;
          }
      
          public void setAge(Integer age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      };
  • 运行结果如下

    • Java高级-反射_第9张图片

你可能感兴趣的:(Java,语言进阶学习,java,开发语言)