Java反射

什么是反射?

反射允许对成员变量,成员方法和构造方法的信息进行编程访问

但是我们不是直接从 .java 文件里面获取的,而是先获取编译后字节码文件 .class,

再从中获取成员变量、构造方法、成员方法

屏幕截图 2026-05-16 084304

获取 class 对象的三种方式

  1. Class.forName("全类名");// 源代码阶段
  2. 类名.class// 加载阶段
  3. 对象.getClass();// 运行阶段

屏幕截图 2026-05-16 084928

package com.faxont.reflect1;

public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            获取 class 对象的三种方式:
            1. Class.forName("全类名");
            2. 类名.class
            3. 对象.getClass();
         */

        // 1. 第一种方式
        // 全类名:包名 + 类名 com.faxont.reflect1.Student
        // 最为常用的
        // 只能写<?>
        Class<?> clazz1 = Class.forName("com.faxont.reflect1.Student");

        // 2. 第二种方式
        // 一般更多的是当作参数进行传递
        // 可以写<?>,也可以写<T>
        Class<Student> clazz2 = Student.class;
        // 例如:synchronized (Student.class){}
//        synchronized (Student.class){
//
//        }

        // 3. 第三种方式
        // 当我们已经有了这个类的对象时,才可以使用
        // 只能写<?>
        Student student = new Student();
        Class<?> clazz3 = student.getClass();

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz1 == clazz3);
        System.out.println(clazz2 == clazz3);
    }
}
package com.faxont.reflect1;

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

    public Student() {
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}

利用反射获取构造方法

Class 类中用于获取构造方法的方法

Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组

Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组

Constructor getConstructor(Class<?>... parameterTypes):返回单个公共构造方法对象

Constructor getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象

Constructor 类中用于创建对象的方法

T newInstance(Object... initargs):根据指定的构造方法创建对象

setAccessible(boolean flag):设置为 true,表示取消访问检查

package com.faxont.reflect2;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;

public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        /*
            Class 类中用于获取构造方法的方法
                Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组
                Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组
                Constructor<T> getConstructor(Class<?>... parameterTypes):返回单个公共构造方法对象
                Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象

            Constructor 类中用于创建对象的方法
                T newInstance(Object... initargs):根据指定的构造方法创建对象
                setAccessible(boolean flag):设置为 true,表示取消访问检查
         */

        // 1. 获取 Class 字节码文件的对象
//        Class<?> clazz = Class.forName("com.faxont.reflect2.Student");
        Class<Student> clazz = Student.class;
        // 2. 获取所有公共构造方法对象(public)
//        Constructor<?>[] cons = clazz.getConstructors();
//        for (Constructor<?> con : cons) {
//            System.out.println(con);
//        }

        // 3. 获取所有构造方法对象
//        Constructor<?>[] cons = clazz.getDeclaredConstructors();
//        for (Constructor<?> con : cons) {
//            System.out.println(con);
//        }

//        Constructor<Student> con1 = clazz.getConstructor();
//        System.out.println(con1);
//        Constructor<Student> con2 = clazz.getDeclaredConstructor(String.class);
//        System.out.println(con2);
//        Constructor<Student> con3 = clazz.getDeclaredConstructor(int.class);
//        System.out.println(con3);
//        System.out.println(con4);
        Constructor<Student> con4 = clazz.getDeclaredConstructor(String.class, int.class);

//        int modifiers = con4.getModifiers();// 获取修饰符
//        System.out.println(modifiers);
//
//        Parameter[] parameters = con4.getParameters();// 获取参数
//        for (Parameter parameter : parameters) {
//            System.out.println(parameter);
//        }

        // 表示临时取消权限的校验(暴力反射)
        con4.setAccessible(true);
        Student student = con4.newInstance("张三", 18);
        System.out.println(student);
    }
}
package com.faxont.reflect2;

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

    public Student() {
    }

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

    protected Student(int age){
        this.age = age;
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}

利用反射获取成员变量

Class 类中用于获取成员变量的方法

Field[] getFields():返回所有公共成员变量对象的数组

Field[] getDeclaredFields():返回所有成员变量对象的数组

Field getField(String name):返回单个公共成员变量对象

Field getDeclaredField(String name):返回单个成员变量对象

Field 类中用于创建对象的方法

void set(Object obj, Object value):赋值

Object get(Object obj):获取值

package com.faxont.reflect3;

import java.lang.reflect.Field;

public class ReflectDemo {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
        /*
            Class 类中用于获取成员变量的方法
                Field[] getFields():返回所有公共成员变量对象的数组
                Field[] getDeclaredFields():返回所有成员变量对象的数组
                Field getField(String name):返回单个公共成员变量对象
                Field getDeclaredField(String name):返回单个成员变量对象

            Field 类中用于创建对象的方法
                void set(Object obj, Object value):赋值
                Object get(Object obj):获取值
         */

        // 1. 获取 Class 字节码文件的对象
        Class<?> clazz = Class.forName("com.faxont.reflect3.Student");

        // 2. 获取所有公共成员变量对象(public)
//        Field[] fields1 = clazz.getFields();
//        for (Field field : fields1) {
//            System.out.println(field);
//        }

        // 3. 获取所有成员变量对象
//        Field[] fields2 = clazz.getDeclaredFields();
//        for (Field field : fields2) {
//            System.out.println(field);
//        }

        Field field1 = clazz.getDeclaredField("name");
//        System.out.println(field1);
        Field field2 = clazz.getDeclaredField("age");
//        System.out.println(field2);
        Field field3 = clazz.getField("sex");
//        System.out.println(field3);
        int modifiers = field1.getModifiers();
        System.out.println(modifiers);

        // 获取成员变量的名字
        String name = field1.getName();
        System.out.println(name);

        // 获取成员变量的数据类型
        Class<?> type = field1.getType();
        System.out.println(type);

        // 获取成员变量记录的值
        Student s = new Student("zhangsan", 18, "男");
        field1.setAccessible(true);
        String value = (String) field1.get(s);
        System.out.println(value);

        // 修改成员变量的值
        field1.set(s, "lisi");
        System.out.println(s);

    }
}
package com.faxont.reflect;

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

    public Student() {
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 获取
     * @return sex
     */
    public String getSex() {
        return sex;
    }

    /**
     * 设置
     * @param sex
     */
    public void setSex(String sex) {
        this.sex = sex;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + ", sex = " + sex + "}";
    }
}

利用反射获取成员方法

Class 类中用于获取成员方法的方法

Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的

Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的

Method getMethod(String name, Class<?>... parameterTypes):返回单个公共成员方法对象

Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象

Method 类中用于创建对象的方法

Object invoke(Object obj, Object... args):运行方法

参数一:用 obj 对象调用该方法

参数二:在调用方法中传递的参数(如果没有就不写)

返回值:方法的返回值(如果没有就不写)

package com.faxont.reflect4;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        /*
            Class 类中用于获取成员方法的方法
                Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
                Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
                Method getMethod(String name, Class<?>... parameterTypes):返回单个公共成员方法对象
                Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象

            Method 类中用于创建对象的方法
                Object invoke(Object obj, Object... args):运行方法
                参数一:用 obj 对象调用该方法
                参数二:在调用方法中传递的参数(如果没有就不写)
                返回值:方法的返回值(如果没有就不写)

            获取方法的修饰符
            获取方法的名字
            获取方法的形参
            获取方法的抛出的异常
         */

        // 1. 获取 Class 字节码文件的对象
        Class<?> clazz = Class.forName("com.faxont.reflect4.Student");

        // 2. 获取所有公共成员方法对象(public)(包含父类中的所有公共方法)
//        Method[] methods1 = clazz.getMethods();
//        for (Method method : methods1) {
//            System.out.println(method);
//        }

        // 3. 获取所有成员方法对象(不包含父类中的方法,但是可以获取本类中私有的方法)
//        Method[] methods2 = clazz.getDeclaredMethods();
//        for (Method method : methods2) {
//            System.out.println(method);
//        }

        // 获取指定的单一方法
        Method m = clazz.getDeclaredMethod("eat", String.class, int.class);
        System.out.println(m);

        // 获取方法的修饰符
        int modifiers = m.getModifiers();
        System.out.println(modifiers);

        // 获取方法名字
        String name = m.getName();
        System.out.println(name);

        // 获取方法的形参
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

        // 获取方法的抛出的异常
        Class<?>[] exceptionTypes = m.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        /*
            Method 类中用于创建对象的方法
                Object invoke(Object obj, Object... args):运行方法
                参数一:用 obj 对象调用该方法
                参数二:在调用方法中传递的参数(如果没有就不写)
                返回值:方法的返回值(如果没有就不写)
         */
        // 方法运行
        Student s = new Student();
        m.setAccessible(true);

        // 获取方法的返回值
        String eat = (String) m.invoke(s, "憨包", 2);
        System.out.println(eat);

    }
}
package com.faxont.reflect4;

import java.io.IOException;

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

    public Student() {
    }

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

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }

    public void sleep(){
        System.out.println("zzz");
    }

    private void eat(String food) {
        System.out.println("在吃" + food);
    }

    private String eat(String food, int count) throws IOException, NullPointerException, ClassCastException {
        System.out.println("吃了" + count + "个" + food);
        return "吃饱了";
    }
}

反射的作用

  1. 获取一个类里面所有的信息,获取到了之后,再执行其它的业务逻辑
  2. 结合配置文件,动态地创建对象并调用方法

练习:保存信息

对于任意一个对象,都可以把对象所有的字段名和值,保存到文件中去

屏幕截图 2026-05-16 102911

package com.faxont.com.practice1;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;

public class Test {
    public static void main(String[] args) {
        /*
            对于任意一个对象,都可以把对象所有的字段名和值,保存到文件中去
         */
        Student s = new Student("小A", 23, '女', 167.5, "睡觉");
        Teacher t = new Teacher("播妞", 10000);
        saveObject(s, "io\\student.txt");
        saveObject(t, "io\\teacher.txt");
    }

    private static void saveObject(Object obj, String fileName){
        Class clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        try(BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))){
            for (Field field : fields) {
                field.setAccessible(true);
                writer.write(field.getName() + "=" + field.get(obj));
                writer.newLine();
            }
        }catch (IOException | IllegalAccessException e){
            e.printStackTrace();
        }
    }
}
package com.faxont.com.practice1;

public class Student {
    private String name;
    private int age;
    private char gender;
    private double height;
    private String hobby;

    public Student() {
    }

    public Student(String name, int age, char gender, double height, String hobby) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.height = height;
        this.hobby = hobby;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 获取
     * @return gender
     */
    public char getGender() {
        return gender;
    }

    /**
     * 设置
     * @param gender
     */
    public void setGender(char gender) {
        this.gender = gender;
    }

    /**
     * 获取
     * @return height
     */
    public double getHeight() {
        return height;
    }

    /**
     * 设置
     * @param height
     */
    public void setHeight(double height) {
        this.height = height;
    }

    /**
     * 获取
     * @return hobby
     */
    public String getHobby() {
        return hobby;
    }

    /**
     * 设置
     * @param hobby
     */
    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + ", gender = " + gender + ", height = " + height + ", hobby = " + hobby + "}";
    }
}
package com.faxont.com.practice1;

public class Teacher {
    private String name;
    private double salary;

    public Teacher() {
    }

    public Teacher(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return salary
     */
    public double getSalary() {
        return salary;
    }

    /**
     * 设置
     * @param salary
     */
    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String toString() {
        return "Teacher{name = " + name + ", salary = " + salary + "}";
    }
}

练习:跟配置文件结合动态创建

反射可以以跟配置文件结合的方式,动态地创建对象,并调用方法

package com.faxont.reflect5;

import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

public class ReflectDemo {
    public static void main(String[] args) {
        /*
            反射可以以跟配置文件结合的方式,动态地创建对象,并调用方法
         */

        // 1. 读取配置文件中的信息
        Properties prop = new Properties();
        try (FileInputStream fis = new FileInputStream("reflect\\prop.properties")){
            prop.load(fis);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(prop);

        // 2. 获取全类名和方法名
        String className = prop.getProperty("classname");
        String methodName = prop.getProperty("method");

        System.out.println(className);
        System.out.println(methodName);

        // 3. 利用反射创建对象并运行方法
        Class clazz = null;
        try {
            clazz = Class.forName(className);
            Constructor con = clazz.getDeclaredConstructor();
            Object o = con.newInstance();
            System.out.println(o);
        } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
package com.faxont.reflect5;

public class Teacher {
    private String name;
    private double salary;

    public Teacher() {
    }

    public Teacher(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public void teach(){
        System.out.println("老师在教书!");
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return salary
     */
    public double getSalary() {
        return salary;
    }

    /**
     * 设置
     * @param salary
     */
    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String toString() {
        return "Teacher{name = " + name + ", salary = " + salary + "}";
    }
}
package com.faxont.reflect5;

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

    public Student() {
    }

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

    public void study(){
        System.out.println("学生在学习!");
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}
classname=com.faxont.reflect5.Student
method=study
posted @ 2026-05-16 21:04  弋湖  阅读(7)  评论(0)    收藏  举报