【Javassist】快速入门系列08 当检测到对象(不包括数组)创建时用代码块替换

news2024/11/25 6:30:37

系列文章目录

01 在方法体的开头或结尾插入代码
02 使用Javassist实现方法执行时间统计
03 使用Javassist实现方法异常处理
04 使用Javassist更改整个方法体
05 当有指定方法调用时替换方法调用的内容
06 当有构造方法调用时替换方法调用的内容
07 当检测到字段被访问时使用语句块替换访问
08 当检测到对象(不包括数组)创建时用代码块替换


文章目录

  • 系列文章目录
  • 前言
  • 引入Javassist jar包
    • 当检测到对象(不包括数组)创建时用代码块替换
  • 总结
  • 说明


前言

上一章我们介绍了当检测到字段被访问时使用语句块替换访问,学习了 method.instrument的用法。以及参数为FieldAccess的重载方法edit的含义。本章主要介绍当检测到对象(不包括数组)创建时用代码块替换。


引入Javassist jar包

在上几篇文章已经引入了javassist的jar包,如果你是第一次观看本系列文章,也可以复制以下maven依赖将jar包导入工程。

        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.28.0-GA</version>
        </dependency>

当检测到对象(不包括数组)创建时用代码块替换

/**
 * 【Javassist】快速入门系列08 当检测到对象(不包括数组)创建时用代码块替换
 * 公众号&B站:精致的王同学
 * @author wangfengxi1
 * @date 2022/12/25 18:02
 */
public class Basic08NewExpr {
    public static void main(String[] args) throws Exception{
        // 获取javassist默认类池
        ClassPool pool = ClassPool.getDefault();
        //获取basic.Basic08Test的ctClass对象
        CtClass ctClass = pool.get("basic.Basic08Test");
        //获取basic.Basic08Test的main方法
        CtMethod method = ctClass.getDeclaredMethod("main");
        // 当检测到对象创建时用代码块替换
        method.instrument(new ExprEditor(){
            @Override
            public void edit(NewExpr e) throws CannotCompileException {
                if (e.getClassName().equals("java.lang.Integer")) {
                    e.replace("System.out.println(\"NewExpr\");$_=$proceed($$);");
                }
            }
        });
        // 将类写成文件
        ctClass.writeFile();
        // 获取修改后的class对象
        Class<?> clazz = ctClass.toClass();
        // 获取修改后的实例
        Object obj = clazz.newInstance();
        // 获取修改后的方法
        Method main = clazz.getDeclaredMethod("main", String[].class);
        // 调用修改后的方法
        main.invoke(obj,(Object) new String[0]);
    }
}

以上Basic08NewExpr类创建了一个main方法,该方法中首先获取javassist的类池pool,然后调用pool.get(“basic.Basic08Test”)方法获取到basic包下的Basic08Test类。Basic08Test类源码如下:

/**
 * 第8节测试类
 *
 * @author wangfengxi1
 * @date 2022/12/26 17:15
 */
public class Basic08Test {
    public static void main(String[] args) {
        Integer integer = new Integer(1);
    }
}

该类中有一个main方法创建了一个Integer 对象

回到Basic08NewExpr 的main方法,在获取到Basic08Test 类的ctClass的对象之后,获取其main方法的方法对象。

接着调用method.instrument(ExprEditor editor)方法搜索method内的对象创建。判断如果其类名是java.lang.Integer,代表该类型的对象被创建。e.replace(“System.out.println(“NewExpr”); = _= =proceed($$);”);表示替换对象创建为代码块的语句。

instrument方法接收一个ExprEditor 类型的对象,该类有很多重载的edit方法,其中参数为NewExpr 的重载方法代表搜索方法内的对象创建(不包含数组创建)。

在替换语句内必须包含 = _= =proceed($$);

在replace的代码块中,以下符号有特殊含义:

$0 null。
$1,$2,  …构造函数的参数。
$_  对象创建的结果值。新创建的对象必须存储在此变量中。
$r  创建对象的类型。
$sig  表示形式参数类型的java.lang.Class对象数组。
$type  表示创建对象的类的java.lang.Class对象。
$proceed  执行原始对象创建的虚拟方法的名称。

最后模拟调用修改后的main方法结果如下:
在这里插入图片描述

总结

本篇文章介绍了使用Javassist当检测到对象(不包括数组)创建时用代码块替换,学习了 method.instrument的用法。以及参数为NewExpr 的重载方法edit的含义。

说明

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker Desktop 4.15 正式发布,这里是新功能

Docker Desktop 4.15 正式发布&#xff0c;这里是新功能 Docker Desktop 4.15现在可用于所有平台&#xff1a;Linux、Windows 和 macOS。它附带 Docker Compose v2.13.0、Containerd v1.6.10 和 Docker Hub Tool v0.4.5 2 主要亮点 VirtioFS 正式发布新的快速搜索功能在任何…

杨校老师课堂之JDK1.8下载、安装与环境变量配置

一、安装 1. 安装引导 2. 修改安装目录(路径) 3. 选择后的路径如下&#xff1a; 4. JRE的安装【可选】 5. 成功安装 二、配置 环境变量配置 1. 进行校验 win R 打开cmd窗口 在新建cmd内&#xff0c;输入javac&#xff0c;出现下列内容&#xff0c;即表示未配置成功。目前尚…

Eclipse 插件 ERMaster安装与使用

ERMaster 是什么&#xff1f; ERMaster是制作ER图&#xff08;Entity Relationship Diagram&#xff0c;实体关系图&#xff09;的Eclipse插件。 提供了从数据库导入、Excel表定义簿制作、图片输出、DDL输出等功能。支持的数据库包括&#xff1a; MySQLOraclePostgreSQLDB2HS…

Windows内核--内核空间和用户空间(3.6)

内核喜欢抽象出句柄给用户空间 句柄, Handle, 表达处理、控制之意。内核不会直接暴露指针给用户空间&#xff0c;这样会增大内核风险。相反&#xff0c;内核抽象出Handle给用户态&#xff0c;不管是文件、进程、线程等对象&#xff0c;通过Handle可以隐藏内核细节&#xff0c;统…

C++不知算法系列之解析回溯算法中的人文哲学

1. 前言 回溯算法让我想起“退一步海阔天空”的名言。当事情的发展到了绝境或是边缘时&#xff0c;可以试着后退一步&#xff0c;换一个方向、换一种策略&#xff0c;或许会看到新的出路或生机。 回溯算法的精髓&#xff1a;无所畏惧而不固执&#xff0c;善于在变通中迂回。故…

基于PyTorch的图像数据归一化min-max normalization和zero-mean normalization操作实践对比分析

本文紧接前文&#xff1a; 《python基于不同方法实现特征工程常用的归一化技术Normalization对比分析》 前文主要是讲解对于数值型特征数据在特征工程或者是数据处理阶段往往需要用到数据尺度归一化操作&#xff0c;基于原生的对象和numpy第三方库分别实现了按列归一化计算和…

一文告诉你什么是开源表单系统

熟悉市场的人都知道&#xff0c;传统的表单存在效率低的瓶颈&#xff0c;无法满足当前很多企业的业务需求。开源表单系统也是顺应时代发展需求应运而生的产物&#xff0c;在提升企业办公效率和协作效率&#xff0c;推动企业数字化转型方面意义重大。今天这篇文章就告诉大家什么…

《计算机网络》——第一章知识点

考试题型: 选择题填空题判断题简答题计算题ISP:因特网服务提供者/因特网服务提供商&#xff0c;是一个向广大用户综合提供互联网接入业务、信息业务、和增值业务的公司&#xff0c;如中国电信、中国联动、中国移动等。分为主干ISP、地区ISP和本地ISP。 计算机网络∶利用通信线…

前端的实例化是什么?

我们在用vue框架的时候&#xff0c;总是会看到各种各样的实例化或者说实例化对象(实例) 所以这篇文章就谈一下什么是实例化和实例化对象(实例)&#xff0c;以及为什么要实例化的问题 前端的实例化是什么&#xff1f;vue的createApppinia的实例化为什么要实例化再一次回答上面这…

关于缓存问题的思考与总结

提到缓存&#xff0c;最容易想到的便是Redis了。Redis凭借其出色的性能表现&#xff0c;十分适合做缓存。那么为什么需要缓存这个东西以及缓存用在哪些地方呢&#xff1f; 一、基本原理 存储层次模型 注&#xff1a;也是背景来源 想要设计好的架构或者应用、程序&#xff0c…

Maven安装配置的保姆级教程

前言 下面是关于maven的一些介绍&#xff1a; maven是一个项目构建和管理的工具&#xff0c;提供了帮助管理 构建、文档、报告、依赖、scms、发布、分发的方法。可以方便的编译代码、进行依赖管理、管理二进制库等等maven的好处在于可以将项目过程规范化、自动化、高效化以及…

C++程序设计——继承与派生

更多内容可以查看系列文章C语言入门全教程&#xff08;持续更新&#xff09; 目录 前言 一、继承的概念 1.楔子 2.派生类的定义 3.继承和派生的意义 4.案例1&#xff1a;派生类的定义 二、继承方式 1.公有继承&#xff08;public&#xff09; 2.保护继承&#xff08;…

网络拓扑结构可视化呈现方案

随着数字化进程的加速&#xff0c;企业网络中设备的数量日益快速增长&#xff0c;网络规模逐渐庞大&#xff0c;组网结构、IT 环境变的无比复杂&#xff0c;需要花费大量的时间和资源去监测网络运行状态&#xff0c;诊断解决故障问题。面对不断趋向复杂化和多样化的网络规模和结…

Mac M1使用Docker报错 Failed to get D-Bus connection: No such file or directory的解决方案

0x00 前言 最近在Mac上安装docker的CentOS7镜像&#xff0c;打算开个sshd服务&#xff0c;使用命令&#xff1a; $ systemctl start sshd结果在启动sshd服务的时候提示报错&#xff1a; Failed to get D-Bus connection: No such file or directory0x01 运行环境 版本MacOS…

《Qt开发》基于QwtPolar的极坐标图绘制

QwtPolar绘制极坐标图 该示例包含以下功能: 使用QwtPolarPlot绘制极坐标曲线实现曲线的缩放和平移调整极坐标为顺时针顺序1. 创建项目 创建项目名称为QwtPolarDemo1&#xff0c;并添加一个Qt5Class类&#xff0c;命名为myPlot。 2. 配置项目 在项目——属性——C/C——常规…

【C++】——初识C++(一)

文章目录1. 进入C1.1 main&#xff08;&#xff09;函数1.2 C注释1.3 C预处理器和iostream文件1.4 头文件名1.5 名称空间1.6 使用cout进行C输出1.6.1 控制符endl1.6.2 换行符1.6.3 使用cout进行拼接1.7 cin1.8 变量1.8.1 变量名1.9 常量1.10 关键字1. 进入C 第一个程序 // my…

构建数据大屏,塑造IT运维可视化核心竞争力

随着大数据、云计算等新兴技术的发展与运用&#xff0c;在金融、交通、教育、政府等行业的信息化在飞速发展。与此同时&#xff0c;各行业的IT建设与维护管理成本也在与日俱增&#xff0c;大量的运维工作下产生庞大的运维数据&#xff0c;如何进行运维数据可视化建设也逐渐成为…

qt之smtp-demo封装与测试

简介 SMTP是一种提供可靠且有效的电子邮件传输的协议&#xff0c;它建立在FTP文件传输服务上的一种邮件服务&#xff0c;主要用于系统之间的邮件信息传递&#xff0c;并提供有关来信的通知。 SMTP的工作过程是建立连接、邮件传送、连接释放。 SMTP的默认端口是25。…

游戏思考26:使用EASTL配合共享内存做自定义STL(未完待续12/27)

文章目录一、前置学习1&#xff09;萃取&#xff08;1&#xff09;迭代器所指对象的类型-value_type<1>第一个限制-返回参数需要指明迭代器的value_type<2>第二个限制坑点-不是所有迭代器都是class type&#xff0c;原生指针就不是<3>第三个限制坑点-如果针对…

2022-12版本的Rstudio它来了,它喊我升级了

1. Rstudio喊我升级 最近每一次打开Rstudio&#xff0c;总是推送给我最新版的Rstudio&#xff1a; 它之前不是这样的&#xff0c;那时候它所在的公司还叫Rstudio&#xff0c;现在改名叫Posit了&#xff0c;就开始推送了&#xff0c;也许它认为是重大的更新&#xff0c;也许他能…