反射的原理和操作

反射是框架设计的灵魂

(使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))

在Java中,反射是指在运行时动态地获取、检查和操作类、对象、方法和属性的能力。Java的反射机制提供了一组API,使程序可以在运行时获取类的信息,并通过这些信息来创建对象、调用方法和访问属性,而无需在编译时提前知道类的具体细节。

通过反射,可以实现以下操作:

  1. 动态创建对象:可以使用反射来实例化一个类的对象,即使在编译时并不知道类的名称。例如,可以动态地根据类名创建对象实例,并调用其方法。

  2. 获取类的信息:可以使用反射来获取类的名称、修饰符、父类、接口等信息。还可以获取类的构造函数、方法和字段的详细信息,包括名称、参数类型、修饰符等。

  3. 调用方法:可以使用反射来调用类的方法,包括公共方法、私有方法和静态方法。通过Method类的实例,可以动态地调用方法并传递参数。

  4. 访问和修改字段:可以使用反射来获取和设置类的字段的值。通过Field类的实例,可以读取和修改对象的字段,包括公共字段和私有字段。

  5. 动态代理:反射还可以用于实现动态代理,即在运行时动态生成代理对象并拦截方法调用。这对于实现AOP(面向切面编程)和其他类似的功能非常有用。

底层原理

通常,java在编译之后,会将Java代码生成为class源文件,JVM启动时,将会载入所有的源文件,并将类型信息存放到方法区中;将所有对象实例存放在Java堆中,同时也会保存指向类型信息的指针。

与直接使用类相反,我们需要先获取到对象在方法区的类型信息,获取到类型信息后,我们就知道这个类的构造器、属性、方法、注解、子类、父类等等信息了,这个时候,我们就可以通过这些类型信息来回调处理对象,来完成自己想要的操作了。

没错,这就是反射的原理了。反射在运行时,通过读取方法区中的字节码,来动态的找到其反射的类以及类的方法和属性等(实际上就是在运行时,根据全类型名在方法区找对应的类),用这些类型信息完成对该类实例的操作,其实就是直接使用类的一个逆向使用。

如果我们动态获取到这些信息,我们需要依靠 Class 对象。Class 类对象将一个类的方法、变量等信息告诉运行的程序。

Java 提供了四种方式获取 Class 对象:

1. 知道具体类的情况下可以使用:

Class alunbarClass = TargetObject.class;

但是我们一般是不知道具体类的,基本都是通过遍历包下面的类来获取 Class 对象,通过此方式获取 Class 对象不会进行初始化

2. 通过 Class.forName()传入类的全路径获取:

Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject");

3. 通过对象实例instance.getClass()获取:

TargetObject o = new TargetObject();
Class alunbarClass2 = o.getClass();

4. 通过类加载器xxxClassLoader.loadClass()传入类路径获取:

ClassLoader.getSystemClassLoader().loadClass("cn.javaguide.TargetObject");

通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一系列步骤,静态代码块和静态对象不会得到执行


   创建一个我们要使用反射操作的类 TargetObject

package cn.javaguide;

public class TargetObject {
    private String value;

    public TargetObject() {
        value = "JavaGuide";
    }

    public void publicMethod(String s) {
        System.out.println("I love " + s);
    }

    private void privateMethod() {
        System.out.println("value is " + value);
    }
}
  1. 使用反射操作这个类的方法以及参数
package cn.javaguide;

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

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {
        /**
         * 获取 TargetObject 类的 Class 对象并且创建 TargetObject 类实例
         */
        Class<?> targetClass = Class.forName("cn.javaguide.TargetObject");
        TargetObject targetObject = (TargetObject) targetClass.newInstance();
        /**
         * 获取 TargetObject 类中定义的所有方法
         */
        Method[] methods = targetClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }

        /**
         * 获取指定方法并调用
         */
        Method publicMethod = targetClass.getDeclaredMethod("publicMethod",
                String.class);

        publicMethod.invoke(targetObject, "JavaGuide");

        /**
         * 获取指定参数并对参数进行修改
         */
        Field field = targetClass.getDeclaredField("value");
        //为了对类中的参数进行修改我们取消安全检查
        field.setAccessible(true);
        field.set(targetObject, "JavaGuide");

        /**
         * 调用 private 方法
         */
        Method privateMethod = targetClass.getDeclaredMethod("privateMethod");
        //为了调用private方法我们取消安全检查
        privateMethod.setAccessible(true);
        privateMethod.invoke(targetObject);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/723102.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

本地部署AI模型-phi3

What&#xff1a; Phi-3-Mini被认为是Microsoft计划发布的三款小型机型中的首款。据报道&#xff0c;在语言、推理、编码和数学等领域&#xff0c;它在各种基准测试中的表现优于相同大小和下一个尺寸的模型。 从本质上讲&#xff0c;语言模型是 ChatGPT、Claude、Gemini 等 AI…

各类存储器类型(RAM、ROM、FLASH、DRAM、SRAM)

1 计算机存储类型构成 在计算机中&#xff0c;各类存储器构成了计算机能高速高效运转程序的基石。 计算机的存储体系中&#xff0c;从速度慢到速度快对应着容量大到小&#xff0c;也就是说&#xff0c;速度越快容量越小&#xff1b;容量越大的&#xff0c;速度越慢。两者互相…

【Python教程】如何搭建一个高效的Python开发环境?结尾附安装包直通车

前言&#xff1a; Python 丰富的函数库和组件库是这门语言强大的核心原因&#xff01;但我们不可能去记忆所有的方法名和参数名&#xff0c;往往只能记住一些常用的或者某个方法开头的几个字母。这个时候一个好的开发工具就需要能聪明地“猜”出你想输入的代码&#xff0c;并给…

怪物猎人物语什么时候上线?游戏售价多少?

怪物猎人物语是一款全新的RPG游戏&#xff0c;玩家在游戏中将化身为骑士&#xff0c;不断与怪物建立羁绊、不断成长&#xff0c;踏上前往外面世界的旅程&#xff0c;且最终目的地是以狩猎怪物为生的猎人世界。因为最近有不少玩家在关注这款游戏&#xff0c;所以下面就给大家分享…

福昕PDF编辑器快速去除PDF水印方法

在福昕PDF编辑器软件中打开一个带有水印的PDF文件&#xff0c;点击如图下所示的页面管理->水印&#xff0c;点击全部移除 点击 是 水印消除&#xff08;注&#xff1a;部分类型的水印可以消除&#xff0c;但是有些类型的水印无法通过此方法消除&#xff09;

day38-39| 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯 62.不同路径 343. 整数拆分 96.不同的二叉搜索树

文章目录 前言动态规划理论基础509. 斐波那契数思路方法一 完整动态规划方法二 dp简化版方法三 使用递归 70. 爬楼梯思路方法一 动态规划方法一2 教程里面的简化方法方法二 拓展 746. 使用最小花费爬楼梯思路方法一方法二 拓展 62.不同路径思路 动态规划方法一方法二 递归 63. …

Java变量:声明、作用域和命名约定

Java变量&#xff1a;声明、作用域和命名约定 什么是变量&#xff1f; 在Java中&#xff0c;变量是保存特定数据类型值的内存位置的名称。它是java编程中的一个基本概念&#xff0c;允许您在程序执行期间存储和操作数据。 Java中的变量可以保存各种类型的数据&#xff0c;包括…

市值飙升!超微软、苹果,英伟达成为全球市值最高上市公司

KlipC报道&#xff1a;当地时间6月18日&#xff0c;英伟达股价再度大涨&#xff0c;盘后股价上涨3.51%&#xff0c;总市值达3.335万亿美元&#xff0c;报135.58美元再刷历史新高&#xff0c;超微软、苹果成为全球市值最高的上市公司。 值得一提的是&#xff0c;在本月初&#x…

记录一次mysql长事务的经历

目录 一.项目介绍 二.问题暴漏 三.问题排查 1.连接池方向 2.数据库方向 四.代码模拟 五.错误原因分析 1.MySQL参数优化 2.代码优化 六.总结 一.项目介绍 项目是springbootnacos的微服务架构,商城购物类系统,分多个服务,问题出现在众多服务中的单个服务 二.问题暴漏…

【AI学习】LLaMA 系列模型的进化(一)

一直对LLaMA 名下的各个模型关系搞不清楚&#xff0c;什么羊驼、考拉的&#xff0c;不知所以。幸好看到两篇综述&#xff0c;有个大致了解&#xff0c;以及SEBASTIAN RASCHKA对LLaMa 3的介绍。做一个记录。 一、文章《Large Language Models: A Survey》中对LLaMa的介绍 论文…

解决 执行 jar 命令 控制台乱码

Springboot项目&#xff0c;编码为utf8 打包后&#xff0c;为了在控制台运行时不乱码&#xff0c;需要在控制台中依次执行以下命令&#xff1a; 第一步&#xff1a; chcp 65001第二步&#xff1a; java -jar -Dfile.encodingutf-8 你的.jar

【GUI软件】小红书蒲公英数据批量采集!高效筛选优质博主,助力品牌商

文章目录 一、背景介绍1.0 爬取目标1.1 演示视频1.2 软件说明 二、代码讲解2.0 关于接口2.1 爬虫采集模块2.2 cookie获取2.3 软件界面模块2.4 日志模块 三、获取采集软件 一、背景介绍 1.0 爬取目标 众所周知&#xff0c;蒲公英是小红书推出的优质创作者商业合作服务平台&…

《庆余年》在前,《玫瑰的故事》在后,阅文发现“新大陆”?

奋笔疾书的网文作家&#xff0c;即将迎来网络文学的高光时代。 近日&#xff0c;阅文集团于安徽省举办2024阅文创作大会。现场数据显示&#xff0c;2023年阅文活跃作家平均收入增长32%&#xff0c;创造近五年最大增幅。其中&#xff0c;中位数作家收入增幅达135%&#xff0c;已…

SSH 远程执行任务

SSH 是 Linux 下进行远程连接的基本工具&#xff0c;但是如果仅仅用它来登录那可是太浪费啦&#xff01;SSH 命令可是完成远程操作的神器啊&#xff0c;借助它我们可以把很多的远程操作自动化掉&#xff01;下面就对 SSH 的远程操作功能进行一个小小的总结。 远程执行命令 如…

ThreeJS-截屏下载pdf或者图片时白屏

JS-页面截图下载为pdf 关于如何下载为 pdf 在上面的这篇文章中有写&#xff0c;大家可以看下&#xff0c;下载图片代码在最下面 这时我们发现 three 部分是空白的如下&#xff1a; 这就多少有点尴尬了&#xff0c;这时我们习惯性的看下后台报错 是不是发现了惊喜&#xff0c;…

操作系统 内存管理

实验目的&#xff1a; 理解虚拟内存在内存管理中的核心作用。掌握常见的内存分配回收算法思想。 实验内容&#xff1a; 编程模拟实现内存伙伴buddy分配器。 实验步骤&#xff1a; 1.理解Buddy分配算法原理&#xff1a; 在开始编码之前,先要深入理解Buddy分配算法的原理。…

Web应用安全测试-综合利用(二)

Web应用安全测试-综合利用&#xff08;二&#xff09; Host头攻击 漏洞描述 Web应用程序获取网站域名一般是依赖HTTP Host header&#xff08;比如在JSP里通过request.getHeader()获取&#xff09;&#xff0c;这里的header很多情况下是不可靠的。 攻击者恶意利用HTTP Host h…

小米HyperOS 澎湃os机型免答题 免社区等级 秒接bl锁操作步骤解析【二】

前面两期博文; 小米HyperOS 澎湃os机型免答题 免社区等级 秒接bl锁操作步骤解析 小米机型解锁bl 绕过社区等级5才可以解锁的限制的教程_没有五级社区怎么解锁bl-CSDN博客 小米对米粉解锁bl是越来越苛刻了。目前社区等级 答题 审核等等步骤越来越繁琐。而且通过率很低。知名开…

细说MCU输出互补型PWM波形时设置死区时间的作用

目录 一、工程背景 二、死区时间的作用 一、工程背景 在作者的文章里建立工程时&#xff0c;为配置输出互补型PWM波形曾经设置了死区时间&#xff0c;DEAD100个定时器的时间周期&#xff08;简称实例1&#xff09;&#xff1a;细说MCU输出互补型PWM波形的实现方法-CSDN博客 …

计算机行业的现状与未来之2024

年年都说编程好&#xff0c;编程工资涨不了。 人家骑车送外卖&#xff0c;月入两万好不好。 一、计算机专业的背景与现状 在过去几十年里&#xff0c;计算机科学相关专业一直是高考考生的热门选择。无论是计算机科学与技术、软件工程&#xff0c;还是人工智能与大数据&#xff…