【Javassist】快速入门系列09 当检测到数组创建时用代码块替换

news2025/1/10 23:54:10

系列文章目录

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


文章目录

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


前言

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


引入Javassist jar包

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

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

当检测到数组创建时用代码块替换

/**
 * 【Javassist】快速入门系列09 当检测到数组创建时用代码块替换
 * 公众号&B站:精致的王同学
 * @author wangfengxi1
 * @date 2022/12/26 17:11
 */
public class Basic09NewArray {
    public static void main(String[] args) throws Exception{
        // 获取javassist默认类池
        ClassPool pool = ClassPool.getDefault();
        //获取basic.Basic08Test的ctClass对象
        CtClass ctClass = pool.get("basic.Basic09Test");
        //获取basic.Basic08Test的main方法
        CtMethod method = ctClass.getDeclaredMethod("main");
        // 当检测到数组创建时用代码块替换
        method.instrument(new ExprEditor(){
            @Override
            public void edit(NewArray a) throws CannotCompileException {
                try {
                    CtClass componentType = a.getComponentType();
                    if (componentType.equals(pool.get("java.lang.Integer"))) {
                        a.replace("System.out.println(\"NewArray\");$_=$proceed($$);");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        // 将类写成文件
        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]);
    }
}ethod main = clazz.getDeclaredMethod("main", String[].class);
        // 调用修改后的方法
        main.invoke(obj,(Object) new String[0]);
    }
}

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

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

该类中有一个main方法创建了一个Integer数组。

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

接着调用method.instrument(ExprEditor editor)方法搜索method内的数组创建。调用a.getComponentType()方法获取数组元素的类型,判断如果是java.lang.Integer,代表该类型的数组被创建。a.replace(“System.out.println(“NewArray”); = _= =proceed($$);”);表示替换数组创建为代码块的语句。

instrument方法接收一个ExprEditor 类型的对象,该类有很多重载的edit方法,其中参数为NewArray的重载方法代表搜索方法内的数组创建
在替换语句内必须包含 = _= =proceed($$);

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

$0  null。
$1,$2,  …每个维度的大小。
$_  数组创建的结果值。新创建的数组必须存储在此变量中。
$r  创建的数组的类型。
$type  表示创建数组的类的java.lang.Class对象。
$proceed  执行原始数组创建的虚拟方法的名称。

最后模拟调用修改后的main方法结果如下:
main方法结果

总结

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

说明

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

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

相关文章

springboot整合之统一结果返回

特别说明&#xff1a;本次项目整合基于idea进行的&#xff0c;如果使用Eclipse可能操作会略有不同&#xff0c;不过总的来说不影响。 springboot整合之如何选择版本及项目搭建 springboot整合之版本号统一管理 springboot整合mybatis-plusdurid数据库连接池 springboot整合…

树与二叉树(遍历)

一、树 树结构是一种非常重要的非线性数据结构&#xff0c;该结构中的一个数据元素可以有两个或者两个以上的直接后继元素。 1、树的定义 树是由 n(n>0)个有限结点组成一个具有层次关系的集合&#xff0c;当 n0时称为空树&#xff0c;当 n>0时称为非空树。 对于非空树来…

水上交通AIS常见问题解决方案

水上交通AIS常见问题解决方案 AIS无信号的几种情况 情况一&#xff1a;AIS未开启。 解决方法&#xff1a;开启AIS设备。 情况二&#xff1a;AIS开启但MMSI码和证书不一致。 解决方法&#xff1a;船长向直属海事部门申请MMSI码&#xff0c;并请专业人员将正确的MMSI码写入AIS设…

数据结构之堆的实现以及实现堆排序和建堆解决Top K问题

文章目录前言1.堆的相关介绍1.什么是堆2.堆的结构2.堆的相关接口具体实现1.堆的声明和堆的初始化2.堆插入数据和删除数据3.堆的其他函数接口3.堆的实际运用1.建堆算法2.堆的应用之堆排序3.堆解决Top k问题4.总结前言 之前对树的相关知识概念进行了简单介绍&#xff0c;本文将实…

odps-jdbc提交MaxCompute数据源SQL报错HTTP/1.0 is not allowed

概述 最近负责的一款数据产品。有个功能&#xff1a;选择某个数据源&#xff0c;比如阿里云的MaxCompute数据源&#xff0c;然后手写SQL&#xff0c;点击自动生成字段&#xff08;即获取前置SQL里的查询字段。前置SQL可以有drop then create table动作子句&#xff0c;但是最后…

【PS-选区速成】快速选择工具、魔棒工具、对象选择工具

目录 快速选择工具 1、位置 2、3种模式&#xff1a;新选区、添加到选区、从选区减去 3、画笔的设置参数 画笔大小&#xff1a;识别的范围 硬度&#xff1a;边缘的识别能力 间距&#xff1a;识别的连贯程度 跟【选区工具】配套使用的快捷键 1、按【ALT】减区 2、放大…

数据结构之排序【快速排序和归并排序的非递归代码实现及分析】

引言&#xff1a; 今天因为要写论文&#xff0c;所以现在有点迟了&#xff0c;并且此时是北京时间&#xff1a;2022/12/28/1:41 ,我发现晚睡我真的是专业的&#xff0c;当然睡觉我也是专业的&#xff0c;懂的都懂&#xff0c;现在有点迟加上天大寒&#xff0c;手指不可屈伸&am…

android之View的滑动

其实不管是哪种滑动方式&#xff0c;基本思想都是类似的&#xff1a;当点击事件传递到View时&#xff0c;系统记下触摸点的坐标&#xff0c;手指移动的时候&#xff0c;系统记下移动后的坐标&#xff0c;并计算出偏移量&#xff0c;并通过偏移量来修改View的坐标。 下面我们来…

黑客比程序员高在哪里?

黑客其实和一般的程序员一样&#xff0c;但是他们的关注点不一样。黑客关注的是如何破坏&#xff0c;通过这些有创造性的破坏来获取利益&#xff0c;展现自己的能力。而程序员关注的是如何创造&#xff0c;通过创造来获取利益&#xff0c;展现自己的能力。 就如同一个硬币的两…

CCF BDCI|算能赛题决赛选手说明论文-01

基于TPU平台实现人群密度估计 加速器队伍 黄显钧 个人名义参赛 中国-广东广州peterhuang0323qq.com 团队简介 加速器队伍队长&#xff1a;黄显钧&#xff0c;现任某科技公司的高级工程师&#xff0c;技术栈涉足嵌入式全栈开发&#xff0c;AI 开发等领域&#xff0c;对技术充满…

云桌面 Vscode 远程debug python

云桌面 Vscode 远程debug python1、进入云桌面2、下载VScode配套软件3、挂载本地磁盘4、安装软件4.1 安装VScode4.2 安装插件vsix文件4.3 在服务端安装vscode server5、VScode 配置6、远程调试6.1 python解释器选择6.2 设置debug7. mtu 配置Author: 沧海一阳1、进入云桌面 根据…

傻白入门芯片设计,盘点计算机体系结构顶会

目录 一、集成电路/半导体领域的三大顶会&#xff1a; &#xff08;1&#xff09;ISSCC &#xff08;2&#xff09;IEDM &#xff08;3&#xff09;VLSI 二、计算机体系结构四大顶会 &#xff08;1&#xff09;ISCA &#xff08;2&#xff09;HPCA &#xff08;3&#x…

42. 网络中的网络(NiN)

LeNet、AlexNet和VGG都有一个共同的设计模式&#xff1a;通过一系列的卷积层与汇聚层来提取空间结构特征&#xff1b;然后通过全连接层对特征的表征进行处理。 AlexNet和VGG对LeNet的改进主要在于如何扩大和加深这两个模块。 或者&#xff0c;可以想象在这个过程的早期使用全连…

利用GithubPage和Hexo搭建个人博客

title: 利用Github搭建个人博客 date: 2022-11-28 20:55:30 tags: [blogs] categories: Hexo 建立Git远程仓库 固定格式为&#xff1a;name.github.io ![]](https://img-blog.csdnimg.cn/fa9d7320d1cc422a8a79f2b41dd8458e.png) 开启Github Pages 设置github的token登陆 连接…

免费在线绘制高颜值,带填充的连贯堆叠柱状图

堆叠柱状图是我们日常工作中经常使用的一类图形。然而当分类较多时&#xff0c;堆叠柱状图看起来不是那么清晰&#xff0c;通过添加额外的连线&#xff0c;可以增加堆叠柱状图的颜值&#xff0c;给人一种连贯的感觉&#xff0c;并且能够更好地观察数据比例的变化。 图1. 堆叠柱…

1.8 异常 模块和包

文章目录了解异常异常的捕获方法为什么需要捕获异常捕获常规的异常捕获指定的异常捕获多个异常捕获所有的异常异常else异常的finally异常的传递Python模块模块的导入自定义模块测试模块\_all\_模块Python包了解异常 当我们的解释器运行时发生了一些没办法的操作&#xff0c;或…

初学Java web(十)

Filter和Listener 一.Filter 概念&#xff1a;Filter表示过滤器&#xff0c;是JavaWeb三大组件(Servlet、Filter、Listener)之一。 过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。 过滤器一般完成一些通用的操作&#xff0c;比如&#xff1a;权限控…

新键盘到了,我的工作效率提升了数十倍

前言&#xff1a;快过年了&#xff0c;找到了一份满意的实习&#xff0c;正好旧的键盘坏掉了&#xff0c;最近入手了一款不错的机械键盘奖励自己。到货使用一段时间了&#xff0c;来一篇键盘开箱的博客做一个反馈。 新键盘使用感言&#xff1a;优良的键盘如图云上漫步&#xf…

白质中的BOLD信号激活检测问题

白质中BOLD信号的生理意义存在争议的两个主要原因&#xff1a; BOLD信号依赖于脑血流量CBF和脑血容量CBV&#xff0c;但是白质中的血流量和血容量比灰质中的少得多&#xff08;利用MRI估计的微血管数量&#xff1a;白质为10-192条/mm^2&#xff0c;灰质为99-761条/mm^2&#x…

【GUI界面】基于Python的WSG84三点定位系统(经纬度坐标与平面坐标转换法求解)

【GUI界面】基于Python的WSG84三点定位系统&#xff08;经纬度坐标与平面坐标转换法求解&#xff09; 方法汇总&#xff1a; blog.csdn.net/weixin_53403301/article/details/128441789 【精准三点定位求解汇总】利用Python或JavaScript高德地图开放平台实现精准三点定位&…