字节码编程ASM之生成变量并sout

写在前面

本文看下如何通过asm生成变量并sout。

1:代码

直接看代码吧,注释很详细,有不懂的,留言告诉我:

package com.dahuyuo.asmtest;import org.objectweb.asm.*;
import org.objectweb.asm.commons.AdviceAdapter;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;import static org.objectweb.asm.Opcodes.ASM5;public class YY extends ClassLoader {public static void main(String[] args) throws Exception {ClassReader cr = new ClassReader("com.dahuyuo.asmtest.XX");ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);cr.accept(new ClassVisitor(ASM5, cw) {public MethodVisitor visitMethod(int access, String name, Stringdescriptor, String signature, String[] exceptions) {// 方法过滤if (!"didi".equals(name)) {return super.visitMethod(access, name, descriptor,signature, exceptions);}MethodVisitor mv = super.visitMethod(access, name, descriptor,signature, exceptions);return new AdviceAdapter(ASM5, mv, access, name, descriptor) {protected void onMethodEnter() {
//                        super.onMethodEnter();// 这里不管定义啥类型都可以用Type.LONG_TYPE,没搞懂是干啥的int intVar1 = newLocal(Type.INT_TYPE); // 创建一个int类型的局部变量 相当于int var;mv.visitLdcInsn(99); // 将常量99加载到操作数栈的栈顶mv.visitVarInsn(ISTORE, intVar1); // 将栈顶值赋值给本地变量 int var = 99;mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); // 将静态变量System.out压倒栈顶mv.visitVarInsn(ILOAD, intVar1); // 将整数变量压到栈顶mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false); // 出栈System.out,整数变量,并调用sout(int)完成输出
////                        int intVar2 = newLocal(Type.INT_TYPE);
//                        mv.visitTypeInsn(NEW, "java/lang/String"); // new String()然后推到栈顶
//                        mv.visitInsn(DUP); // 复制栈顶元素int nextLocal = this.nextLocal; // 获取当前可用的局部变量表位置??mv.visitLdcInsn("pppp"); // 加载常量到栈顶mv.visitVarInsn(ASTORE, nextLocal); // 将栈顶string对象复制给局部变量
//                        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/String", "<init>", "(Ljava/lang/String;)V", false); // 调用构造函数完成string对象创建
//                        mv.visitVarInsn(ASTORE, this.nextLocal);mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); // 将静态变量System.out压倒栈顶mv.visitVarInsn(ALOAD, nextLocal); // 将string变量压到栈顶mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); // 出栈System.out,整数变量,并调用sout(string)完成输出}public void visitMaxs(int maxStack, int maxLocals) {super.visitMaxs(maxStack, maxLocals);}protected void onMethodExit(int opcode) {super.onMethodExit(opcode);}};}}, ClassReader.EXPAND_FRAMES);// 获取后的字节码byte[] byteAfterInstrument = cw.toByteArray();outputClazz(byteAfterInstrument, "xxvv");// 测试方法Class<?> clazz = newYY().defineClass("com.dahuyuo.asmtest.XX", byteAfterInstrument, 0, byteAfterInstrument.length);Method didi = clazz.getMethod("didi");didi.invoke(clazz.newInstance());}private static void outputClazz(byte[] bytes, String className) {// 输出类字节码FileOutputStream out = null;try {String pathName = YY.class.getResource("/").getPath() + className + "_after_instrument.class";out = new FileOutputStream(new File(pathName));System.out.println("插桩后代码输出路径:" + pathName);out.write(bytes);} catch (Exception e) {e.printStackTrace();} finally {if (null != out) try {out.close();} catch (IOException e) {e.printStackTrace();}}}
}

用来进行插桩的XX类如下:

public class XX {/*  public static void main(String[] args) {int a = 10;int b = 20;System.out.println(a + b);}*/public void didi() {}
}

运行测试:
在这里插入图片描述
查看生成的字节码:
在这里插入图片描述
就是我们要的效果。

写在后面

参考文章列表

JVM 虚拟机字节码指令表 。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VCS+Vivado联合仿真BUG

场景&#xff1a; 在vcsvivado联合仿真过程中&#xff0c;对vivado导出的shell脚本修改&#xff0c;修改某些source文件路径&#xff0c;vcs编译时会报Permission Denied。 问题描述 对shell脚本修改如下&#xff1a; 修改仅为注释掉某一行&#xff0c;下面变为source文件新…

Linux shell编程学习笔记62: top命令 linux下的任务管理器

0 前言 top命令是Unix 和 Linux下常用的性能分析工具&#xff0c;提供了一个动态的、交互式的实时视图&#xff0c;显示系统的整体性能信息&#xff0c;以及正在运行的进程的相关信息&#xff0c;包括各个进程的资源占用状况&#xff0c;类似于Windows的任务管理器。 1 top命令…

数据特征采样在 MySQL 同步一致性校验中的实践

作者&#xff1a;vivo 互联网存储研发团队 - Shang Yongxing 本文介绍了当前DTS应用中&#xff0c;MySQL数据同步使用到的数据一致性校验工具&#xff0c;并对它的实现思路进行分享。 一、背景 在 MySQL 的使用过程中&#xff0c;经常会因为如集群拆分、数据传输、数据聚合等…

【堆 优先队列】23. 合并 K 个升序链表

本文涉及知识点 堆 优先队列 LeetCode23. 合并 K 个升序链表 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 1&#xff1a; 输入&#xff1a;lists [[1,4,5],[1,3,4],[2,6]] 输出&#…

基流科技:超算界的新星,Pre-A轮融资大获成功

基流科技:超算界的新星,Pre-A轮融资大获成功! 在科技的浪潮中,一颗新星正在冉冉升起——基流科技,一家开放算力网络提供商,以其革命性的技术在超算界引起了轰动。今年年初,基流科技完成了 Pre-A 轮融资,由光速光合领投,此前已获得奇绩创坛、微梦传媒等知名投资方的青…

mysql定时备份数据库

文章目录 核心目标思路具体方法一、编写脚本二、修改文件属性三、找一个mysqldump文件四、把.sh放到定时器里 其它&#xff1a;windows的脚本 核心目标 解决数据库定时备份的工作。centos环境。 思路 用centos的crontab定时执行脚本。 具体方法 一、编写脚本 编写backup_…

Kafka集群部署(手把手部署图文详细版)

1.1.1 部署zookpeer 在node02下载并解压zookeeper软件包 cd /usr/local wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz 或者&#xff1a;scp cat192.168.28.100:/home/cat/zookeeper-3.4.6.tar.gz /tmp&#xff08;注意目录&#xf…

鸿蒙小案例-首选项工具类

一个简单的首选项工具类 主要提供方法 初始化 init()方法建议在EntryAbility-》onWindowStageCreate 方法中使用 没多少东西&#xff0c;放一下测试代码 import { PrefUtil } from ./PrefUtil; import { promptAction } from kit.ArkUI;Entry Component struct PrefIndex {St…

计算机的错误计算(二十一)

摘要 两个不相等数相减&#xff0c;差为0&#xff1a; ? 在计算机的错误计算&#xff08;十九&#xff09;中&#xff0c;高中生小明发现本应为0的算式结果不为0. 今天他又发现对本不为0的算式&#xff0c;计算机的输出为0. 在 Python 中计算 &#xff1a; 则输出为0. 若用 C…

@react-google-maps/api实现谷歌地图嵌入React项目中,并且做到点击地图任意一处,获得它的经纬度

1.第一步要加入项目package.json中或者直接yarn install它都可以 "react-google-maps/api": "^2.19.3",2.加入项目中 import AMapLoader from amap/amap-jsapi-loader;import React, { PureComponent } from react; import { GoogleMap, LoadScript, Mar…

RabbitMQ消息可靠性等机制详解(精细版三)

目录 七 RabbitMQ的其他操作 7.1 消息的可靠性(发送可靠) 7.1.1 confim机制(保证发送可靠) 7.1.2 Return机制(保证发送可靠) 7.1.3 编写配置文件 7.1.4 开启Confirm和Return 7.2 手动Ack(保证接收可靠) 7.2.1 添加配置文件 7.2.2 手动ack 7.3 避免消息重复消费 7.3.…

JAVA:文件防重设计指南

1、简述 在现代应用程序中&#xff0c;处理文件上传是一个常见的需求。为了保证文件存储的高效性和一致性&#xff0c;避免重复存储相同的文件是一个重要的优化点。本文将介绍一种基于哈希值的文件防重设计&#xff0c;并详细列出实现步骤。 2、设计原理 文件防重的基本思路…

如何使用 3D 建模库在 C# 中将 3DS 转换为 USDZ?

USDZ/USD是一种 3D 文件格式&#xff0c;被广泛用于跨平台共享 3D 资产。另一方面&#xff0c;3DS是另一种以块形式存储数据的 3D 文件格式。在某些情况下&#xff0c;您需要将3DS 文件转换为 USDZ/USD文件格式。因此&#xff0c;本篇博文介绍了一个功能丰富的3D 建模库&#x…

6月30日功能测试Day10

3.4.4拼团购测试点 功能位置&#xff1a;营销-----拼团购 后台优惠促销列表管理可以添加拼团&#xff0c;查看拼团活动&#xff0c;启动活动&#xff0c;编辑活动&#xff0c;删除活动。 可以查看拼团活动中已下单的订单以状态 需求分析 功能和添加拼团 商品拼团活动页 3…

【Sping Boot2】笔记

Spring Boot 2入门 如何创建一个Spring Boot的Web例子&#xff1f;1.如何创建一个Spring Boot项目1.1 使用Maven构建一个Spring Boot 2项目1.1.1创建Maven工程注&#xff1a;Maven项目结构&#xff1a; 1.1.2引入SpingBoot相关依赖依赖注意事项&#xff1a; 1.1.3创建主类1.1.4…

传统数据处理系统存在的问题

传统应用的数据系统架构设计时&#xff0c;应用直接访问数据库系统。当用户访问量增加时&#xff0c;数据库无法支撑日益增长的用户请求的负载&#xff0c;从而导致数据库服务器无法及时响应用户请求&#xff0c;出现超时的错误。 出现这种情况以后&#xff0c;在系统架构上就采…

【python】OpenCV—Nighttime Low Illumination Image Enhancement

文章目录 1 背景介绍2 代码实现3 原理分析4 效果展示5 附录np.ndindexnumpy.ravelnumpy.argsortcv2.detailEnhancecv2.edgePreservingFilter 1 背景介绍 学习参考来自&#xff1a;OpenCV基础&#xff08;24&#xff09;改善夜间图像的照明 源码&#xff1a; 链接&#xff1a…

Word “当前页“ 与 “前一页“ (含部分内容)间有大半页空白,删除空白方法

鼠标光标选中需要向上移的句子&#xff0c;右键点击“段落”&#xff0c;然后在跳出的窗口中按照“换行和分页”中的红色方框内取消勾选后&#xff0c;点击确定即可。

Python | Leetcode Python题解之第216题组合总和III

题目&#xff1a; 题解&#xff1a; class Solution:def combinationSum3(self, k: int, n: int) -> List[List[int]]:"""回溯法&#xff0c;对于当前k和n, 枚举元素"""def backtracking(k: int, n: int, ans: List[int]):if k 0 or n <…

《米小圈日记魔法》边看边学,轻松掌握写日记的魔法!

在当今充满数字化娱乐和信息快速变迁的时代&#xff0c;如何创新引导孩子们学习&#xff0c;特别是如何培养他们的写作能力&#xff0c;一直是家长和教育者们关注的焦点。今天就向大家推荐一部寓教于乐的动画片《米小圈日记魔法》&#xff0c;该系列动画通过其独特的故事情节和…