反射的作用
反射的核心作用:动态性.反射让程序在运行时动态操作类和对象,而不是在编译时写死代码.就像给程序装了一个”扫描仪”,可以实时监测未知的类结构
反射的基础实现:Class对象
Class对象简单来说就是类的”身份证”

对于每一个类来说比如(String,ArrayList),在JVM中都有一个对应的Class对象,这个Class对象记录了这个类的所有消息包括:类名,方法,字段,构造器等等

更加贴切的类比

假设要组装一个电脑

类:相当于电脑的设计图纸
对象:根据图纸造出的实体电脑
Class对象:图纸的索引卡片(记录,图纸存放的位置,版本号,需要的零件信息)
若你要查看图纸,不是直接对图纸进行操作,而是通过索引卡片(Class对象)找到图纸信息

获取Class对象的方法
类名.class

    //类名.class(最直接)
    Class<String> stringClass = String.class;

明确知道要操作的类,编译时检查类是否存在
对象.getClass()

    //对象.getClass()
    String str = "Hello World";
    Class<?> strClass = str.getClass();

前提已经存在对象实例,只能获取对象实例类型的Class
Class.forName()
//Class.forName("完整类名")最灵活

    Class<?> arrayListClass = Class.forName("java.lang.ArrayList");

动态加载类(根据配置),必须完成输入类型(包名+类名)
Class对象的主要作用
通过Class对象,我们可以”解剖一个类”

创建对象:即使不知道类名,也可以创建
查看类信息:包括类名,包名,父类信息,接口等等
获取所有方法和字段:甚至包括私有方法
调用方法:包括私有方法
动态操作字段值
Class对象获取构造函数方法
获取构造函数方法
Constructor<?>[] getConstructors():获取所有public构造函数方法

//获取类的所有public构造函数

    Constructor<?>[] constructors = stuClass.getConstructors();

Constructor<?>[] getDeclaredConstructors():获取所有的构造函数包括private

//获取类所有的构造函数包括private

    Constructor<?>[] declaredConstructors = stuClass.getDeclaredConstructors();

Constructor<T> getConstructor(Class<?>... paramTypes):获取无参或有参构造函数的

//获取无参构造函数public

    Constructor<Student> classConstructor = stuClass.getConstructor();

Constructor<T> getDeclaredConstructor(Class<?>... paramTypes):获取任意访问权限的构造函数

    //获取有参构造函数private,需传入参数类型的Class对象
    Constructor<Student> declaredConstructor = stuClass.getDeclaredConstructor(Integer.class);
    declaredConstructor.setAccessible(true);//将访问权限置为true

通过构造函数创建对象的方法
T newInstance(Object... args)

使用构造函数创建实例:

    //无参构造函数创建对象
    Constructor<Student> constructor = Student.class.getConstructor();
    Student student = constructor.newInstance();

    //有参构造函数创建对象
    Constructor<Student> constructor1 = Student.class.getConstructor(String.class, Integer.class);
    Student student1 = constructor1.newInstance("张三",18);

字段操作
获取字段

Field[] getFields():获取所有public字段,包括父类

    //获取所有public字段
    Field[] fields = Student.class.getFields();

Field[] getDeclaredFields():获取本类所有字段,包括private

    //获取本类所有字段包括private字段
    Field[] declaredFields = Student.class.getDeclaredFields();

Field getField(String name):获取指定名称的public字段

    //获取指定名称的public字段
    Field name = Student.class.getField("name");

Field getDeclaredField(String name):获取任意访问权限的字段

    //获取任意访问权限的字段
    Field age = Student.class.getDeclaredField("age");

操作字段值

Object get(Object obj):获取字段值

    Field age = Student.class.getDeclaredField("age");
    age.setAccessible(true);
             Integer num = (Integer) age.get(student);

void set(Object obj,Object value:修改字段值

    Student student = new Student();
    Field nameField = Student.class.getDeclaredField("name");

    nameField.setAccessible(true);//突破访问权限
    nameField.set(student, "zhangsan");

方法操作
获取方法

Method[] getMethods():获取所有public方法

    //获取所有public方法包括父类
    Method[] methods = Student.class.getMethods();

Method[] getDeclaredMethods():获取所有方法包括private

    //获取所有private方法
    Method[] declaredMethods = Student.class.getDeclaredMethods();

Method[] getMethod(String name,Class<?>... paramTypes)获取指定参数的public方法

    //获取指定参数的public方法
    Method setName = Student.class.getMethod("setName", String.class);
    Method setAge = Student.class.getMethod("setAge", Integer.class);

Method[] getDeclaredMethod(String name,Class<?>... paramTypes)

    //获取任意访问权限的方法
    Method getName = Student.class.getDeclaredMethod("getName");
    getName.setAccessible(true);

调用方法

Object invoke(Object obj, Object... args):调用方法

    Student student = new Student();
    Method getName = Student.class.getDeclaredMethod("getName");
    String name = (String) getName.invoke(student);

案例理解
封装一个通用方法,支持传入各种的对象类型都可以实现对应方法

/*
 * @description:封装一个通用方法,支持传入各种的对象类型都可以实现对应方法
 * @author: HYJ
 * @date: 2025/2/17 10:25
 * @param: [className, methodName]
 * @return: void
 **/
public static void invoke(String className, String methodName) {

    try {
        //获取Class对象
        Class<?> clazz = Class.forName(className);
        //获取构造器
        Constructor<?> constructor = clazz.getConstructor();

        //实例化对象
        Object instance = constructor.newInstance();

        //获取方法
        Method method = clazz.getMethod(methodName);

        //调用method的invoke执行方法
        method.invoke(instance);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

4txutgih
1 声望0 粉丝

下一篇 »
创建型模式