Java反射机制

反射是什么

官方定义:在运行时可以动态地获取类的信息,并操作类属性和方法的能力**(不需要提前知道这个类的具体细节)**.简单来说,假设你有一个盒子,盒子里装满了玩具.正常的操作是:你已知盒子里是什么玩具,可以直接取出来.反射操作:闭着眼在盒子里摸索,通过形状,重量猜出是什么玩具

反射的作用

  • **反射的核心作用:动态性.**反射让程序在运行时动态操作类和对象,而不是在编译时写死代码.就像给程序装了一个"扫描仪",可以实时监测未知的类结构

反射的基础实现:Class对象

Class对象简单来说就是类的"身份证"

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

  • 更加贴切的类比

    假设要组装一个电脑

    • 类:相当于电脑的设计图纸
    • 对象:根据图纸造出的实体电脑
    • Class对象:图纸的索引卡片(记录,图纸存放的位置,版本号,需要的零件信息)

    若你要查看图纸,不是直接对图纸进行操作,而是通过索引卡片(Class对象)找到图纸信息

获取Class对象的方法

类名.class

java 复制代码
        //类名.class(最直接)
        Class<String> stringClass = String.class;
  • 明确知道要操作的类,编译时检查类是否存在

对象.getClass()

java 复制代码
        //对象.getClass()
        String str = "Hello World";
        Class<?> strClass = str.getClass();
  • 前提已经存在对象实例,只能获取对象实例类型的Class

Class.forName()

java 复制代码
//Class.forName("完整类名")最灵活
        Class<?> arrayListClass = Class.forName("java.lang.ArrayList");
  • 动态加载类(根据配置),必须完成输入类型(包名+类名)

Class对象的主要作用

通过Class对象,我们可以"解剖一个类"

  • 创建对象:即使不知道类名,也可以创建
  • 查看类信息:包括类名,包名,父类信息,接口等等
  • 获取所有方法和字段:甚至包括私有方法
  • **调用方法:**包括私有方法
  • 动态操作字段值

Class对象获取构造函数方法

获取构造函数方法

  • Constructor<?>[] getConstructors():获取所有public构造函数方法

    java 复制代码
     //获取类的所有public构造函数
            Constructor<?>[] constructors = stuClass.getConstructors();
  • Constructor<?>[] getDeclaredConstructors():获取所有的构造函数包括private

    java 复制代码
     //获取类所有的构造函数包括private
            Constructor<?>[] declaredConstructors = stuClass.getDeclaredConstructors();
  • Constructor<T> getConstructor(Class<?>... paramTypes):获取无参或有参构造函数的

    java 复制代码
     //获取无参构造函数public
            Constructor<Student> classConstructor = stuClass.getConstructor();
  • Constructor<T> getDeclaredConstructor(Class<?>... paramTypes):获取任意访问权限的构造函数

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

通过构造函数创建对象的方法

  • T newInstance(Object... args)

    • 使用构造函数创建实例:
    java 复制代码
            //无参构造函数创建对象
            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字段,包括父类

      java 复制代码
              //获取所有public字段
              Field[] fields = Student.class.getFields();
    • Field[] getDeclaredFields():获取本类所有字段,包括private

      java 复制代码
              //获取本类所有字段包括private字段
              Field[] declaredFields = Student.class.getDeclaredFields();
    • Field getField(String name):获取指定名称的public字段

      java 复制代码
              //获取指定名称的public字段
              Field name = Student.class.getField("name");
    • Field getDeclaredField(String name):获取任意访问权限的字段

      java 复制代码
              //获取任意访问权限的字段
              Field age = Student.class.getDeclaredField("age");
  • 操作字段值

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

      java 复制代码
              Field age = Student.class.getDeclaredField("age");
              age.setAccessible(true);
      				 Integer num = (Integer) age.get(student);
    • void set(Object obj,Object value:修改字段值

      java 复制代码
              Student student = new Student();
              Field nameField = Student.class.getDeclaredField("name");
      
              nameField.setAccessible(true);//突破访问权限
              nameField.set(student, "zhangsan");

方法操作

  • 获取方法

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

      java 复制代码
              //获取所有public方法包括父类
              Method[] methods = Student.class.getMethods();
    • Method[] getDeclaredMethods():获取所有方法包括private

      java 复制代码
              //获取所有private方法
              Method[] declaredMethods = Student.class.getDeclaredMethods();
    • Method[] getMethod(String name,Class<?>... paramTypes)获取指定参数的public方法

      java 复制代码
              //获取指定参数的public方法
              Method setName = Student.class.getMethod("setName", String.class);
              Method setAge = Student.class.getMethod("setAge", Integer.class);
    • Method[] getDeclaredMethod(String name,Class<?>... paramTypes)

      java 复制代码
              //获取任意访问权限的方法
              Method getName = Student.class.getDeclaredMethod("getName");
              getName.setAccessible(true);
  • 调用方法

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

      java 复制代码
              Student student = new Student();
              Method getName = Student.class.getDeclaredMethod("getName");
              String name = (String) getName.invoke(student);

案例理解

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

java 复制代码
    /*
     * @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();
        }
    }
相关推荐
励志成为糕手2 天前
编程语言Java——核心技术篇(一)封装、继承和多态
java·开发语言·ide·java开发
lili-felicity8 天前
《5分钟开发订单微服务!飞算JavaAI实战:IDEA插件安装→空指针修复→K8s部署全流程》
java开发·飞算javaai炫技赛
Francek Chen14 天前
【飞算JavaAI】一站式智能开发,驱动Java开发全流程革新
人工智能·ai编程·java开发·飞算javaai·炫技赛
摘星编程15 天前
飞算JavaAI:新一代智能编码引擎,革新Java研发范式
java开发·飞算javaai·智能编码引擎·人工智能编程·研发范式革新
♡喜欢做梦15 天前
飞算 JavaAI 深度体验:开启 Java 开发智能化新纪元
java开发·飞算javaai炫技赛
guslegend17 天前
飞算AI-idea强大的AI工具
java开发·飞算javaai炫技赛
linweidong19 天前
七牛云Java开发面试题及参考答案(60道面试题汇总)
spring·读写分离·aop·cap·java开发·spring ioc·java面经
在未来等你20 天前
设计模式精讲 Day 22:模板方法模式(Template Method Pattern)
设计模式·模板方法模式·软件架构·java开发·面向对象设计·设计模式实战·java应用开发
小凡敲代码3 个月前
美团Java后端二面面经!
java·程序员·java面试·java面试题·java开发·java场景题·美团java后端
ihav2carryon4 个月前
Mybatis-Plus知识点详解
#java开发#java·#后端开发·#mybatis-plus