写点什么

Java 反射机制

  • 2025-02-20
    福建
  • 本文字数:2901 字

    阅读完需:约 10 分钟

反射是什么


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


反射的作用


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


反射的基础实现: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(); } }
复制代码


文章转载自:ihave2carryon

原文链接:https://www.cnblogs.com/ihave2carryon/p/18725027

体验地址:http://www.jnpfsoft.com/?from=001YH

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
Java反射机制_Java_不在线第一只蜗牛_InfoQ写作社区