十二,反射

42 阅读3分钟

一,反射概述

image-20240607222327413

反射学习目录:

image-20240607222443932

二,获取class对象

image-20240607222541248

三,获取类中信息

利用class类获取类中的信息方法:

  1. 通过Constructorfieldmethod判断这个方法是获取构造方法,成员变量,成员方法。
  2. 如果加上了Declared代表获取所有的类型的东西
  3. 最后末尾加上s代表获取所有
  4. 一般格式为get+Delcared(可以不加,不加代表只获得公共的)+Constructor/field/method+s(这个s可以不加代表获取指定的)

3.1 反射获取构造方法

image-20240607223308529

代码举例:

Student类

package domain;

public class Student {
    private int age;
    private String name;

    public Student() {
        System.out.println("无参构造器执行了~")
    }

    public Student(String name, int age) {
        System.out.println("有参构造器执行了~")
        this.name = name;
        this.age = age;
    }
}

测试类:

    @Test
    public void testRelfct() throws NoSuchMethodException {
        Class<Student> studentClass = Student.class;

        //1.获取全部public修饰的构造器
        Constructor<?>[] constructors1 = studentClass.getConstructors();
        //2.获取全部的构造器
        Constructor<?>[] constructors2 = studentClass.getDeclaredConstructors();

        //3.获取public修饰的指定构造器
        //获取指定public修饰的无参构造
        Constructor<Student> constructor1 = studentClass.getConstructor();
        //获取指定public修饰的有参构造
        Constructor<Student> constructor2 = studentClass.getConstructor(String.class,int.class);
        //获取指定无参构造
        Constructor<Student> declaredConstructor1 = studentClass.getDeclaredConstructor();
        //获取指定有参构造
        Constructor<Student> declaredConstructor2 = studentClass.getDeclaredConstructor(String.class,int.class);
    }

获取类构造器的作用:依然是初始化对象返回

image-20240607224824293

    @Test
    public void testRelfct() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<Student> studentClass = Student.class;

        //获取指定无参构造(反射一般不会填写数据类型,为了确保代码的通用性)
        Constructor<Student> declaredConstructor1 = studentClass.getDeclaredConstructor();
        //获取指定有参构造(反射一般不会填写数据类型,为了确保代码的通用性)
        Constructor<Student> declaredConstructor2 = studentClass.getDeclaredConstructor(String.class,int.class);
        //调用构造器创建对象(如果构造器是private修饰的就必须设置为可访问)
        declaredConstructor1.setAccessible(true);
        Student student = declaredConstructor1.newInstance();
        Student student1 = declaredConstructor2.newInstance("张三", 18);
    }

3.2 反射获取字段(成员变量)

image-20240607225350466

代码举例:

Student类

package domain;

public class Student {
    public static int a;
    public static final String COUNTRY="中国";
    private int age;
    private String name;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

测试类:

    @Test
    public void testRelfct() throws NoSuchFieldException {
        Class<Student> studentClass = Student.class;
        //1.获取全部public修饰的成员变量
        Field[] fields = studentClass.getFields();
        //2.获取全部成员变量
        Field[] declaredFields = studentClass.getDeclaredFields();
        //3.获取指定public修饰的成员变量
        Field name = studentClass.getField("name");
        //4.获取指定成员变量
        Field age = studentClass.getDeclaredField("age");
    }

获取到成员变量的作用:依然是赋值、取值。

image-20240607230212088

    @Test
    public void testRelfct() throws NoSuchFieldException, IllegalAccessException {
        Class<Student> studentClass = Student.class;

        Field name = studentClass.getDeclaredField("name");
        Student s=new Student("张三",13);
        System.out.println(s.getName()+":"+s.getAge());
        name.setAccessible(true);//禁止访问权限检查,进行暴力反射
        name.set(s,"李四");//将对象s的name属性设置为"李四"
        System.out.println(s.getName()+":"+s.getAge());
        System.out.println(name.get(s));//获取对象s的name属性的值
    }

3.3 反射获取成员方法

image-20240607230850026

代码举例:

Student类

package domain;

public class Student {
    public static int a;
    public static final String COUNTRY="中国";
    private int age;
    private String name;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void eat(){
        System.out.println("吃");
    }
    public void eat(String name){
        System.out.println(name+"吃");
    }
    private void move(String name){
        System.out.println(name+"移动");
    }
}

测试类:

    @Test
    public void testRelfct() throws NoSuchMethodException {
        Class<Student> studentClass = Student.class;

        //1.获取所有public修饰的方法
        Method[] methods = studentClass.getMethods();
        //2.获取所有方法
        Method[] declaredMethods = studentClass.getDeclaredMethods();
        //3.获取指定方法
        Method eat1 = studentClass.getMethod("eat");//获取public修饰的无参eat方法
        Method eat2 = studentClass.getMethod("eat", String.class);//获取public修饰的有参eat方法
        //获取有参eat方法
        Method eat3 = studentClass.getDeclaredMethod("eat");//获取public修饰的无参eat方法
        Method eat4 = studentClass.getDeclaredMethod("eat", String.class);
        
    }

成员方法的作用:依旧是执行

image-20240607231327333

    @Test
    public void testRelfct() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<Student> studentClass = Student.class;

        Method move = studentClass.getDeclaredMethod("move",String.class);

        Student s=new Student("张三",13);
        move.setAccessible(true);//设置访问权限,暴力反射
        move.invoke(s,"小猫");//调用对象s的move方法
    }

四,反射的作用

image-20240607232004265