【JavaSE】反射

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、概念

反射是在运行期间动态获取对象的属性和方法

二、相关的类

在Java的反射里主要有以下几个类Class类这是反射的起源反射必须要先获取Class对象其次是Field类当我们需要通过反射获取私有字段时就需要用到这个类Method类同理我们获取私有方法时就需要用到这个类

三、获取Class对象

要进行反射就必须先获取目标类对应的Class对象主要有以下三种方法

我们先定义一个学生类主要字段有姓名、班级、年龄都是私有其中一个公开的无参构造方法一个私有含参构造方法还有一个私有的eat方法

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

    public Student() {
    }

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

    private void eat(String s){
        System.out.println(this.classes + "的" + this.name +"上课偷吃"+s);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", classes='" + classes + '\'' +
                ", age=" + age +
                '}';
    }
}

然后我们通过以下三种方法获取Class对象

    • 目标类.class

public class GetConstruct {
    public static void main(String[] args) {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        Class<?> c2 = new Student().getClass();
        Class<?> c3 = Class.forName("Student");
    }
}
    • 目标类实例.getClass()

    • Class.forName(目标类名)

三、反射创建实例

获取到Class实例后就可以通过Class实例的方法来构造目标类的对象

    • Class类的newInstance方法

public class GetConstruct {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        Class<?> c2 = new Student().getClass();
        //Class<?> c3 = Class.forName("反射.Student");
        
        //2.创建实例
        Student student1 = (Student) c1.newInstance();
    }
}
    • 通过获取目标类的私有构造方法

先获取Class对象然后利用他的getDeclaredConstructor方法获取私有构造方法

public class GetConstruct {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        Class<?> c2 = new Student().getClass();
        //Class<?> c3 = Class.forName("反射.Student");

        //2.创建实例
        Constructor<?> constructor = c1.getDeclaredConstructor(String.class,String.class,int.class);
        constructor.setAccessible(true);  //确认获取
        Student student = (Student) constructor.newInstance("张三","21级3班",21);//传入参数

        //3.验证
        System.out.println(student);
    }
}

四、反射获取私有字段

依旧先是获取Class对象然后利用反射创建目标类的实例 最后使用Field类获取修改字段

public class GetField {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        //Class<?> c2 = new Student().getClass();
        //Class<?> c3 = Class.forName("反射.Student");

        //2.创建目标类实例
        Constructor<?> constructor = c1.getDeclaredConstructor(String.class,String.class,int.class);
        constructor.setAccessible(true);
        Student student = (Student) constructor.newInstance("张三","21级4班",21);

        //3.利用Field类的方法修改字段
        Field field = c1.getDeclaredField("name");   //参数传入要获取的字段名
        field.setAccessible(true);                         //确认获取
        field.set(student,"李四");                          //参数要修改的目标实例新字段的值

        //4.验证
        System.out.println(student);
    }
}

五、反射获取私有方法

先获取Class实例然后创建目标类对象再通过Method类进行获取调用 方法获取目类i私有方法

public class GetMethod {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        //Class<?> c2 = new Student().getClass();
        //Class<?> c3 = Class.forName("反射.Student")/

        //2.创建目标类实例
        Constructor<?> constructor = c1.getDeclaredConstructor(String.class,String.class,int.class);
        constructor.setAccessible(true);
        Student student = (Student) constructor.newInstance("张三","21级4班",21);

        //3.通过Method方法获取
        Method method = c1.getDeclaredMethod("eat",String.class);  //参数传入要获取的方法名
        method.setAccessible(true);                         //确认获取
        method.invoke(student,"零食");                             //传入目标类的实例与函数参数
    }
}

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java