asm生成for循环语句方法
asm生成for循环语句方法
1.jar包
2.原java文件
package club.jiajia.test3;
public class Examp4 {
public int method(int a){
int r=0;
for(int i=0;i<a;i++){
r++;
}
return r;
}
}
3.javap -c命令反编译此java的字节码文件
Compiled from "Examp4.java"
public class club.jiajia.test3.Examp4 {
public club.jiajia.test3.Examp4();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public int method(int);
Code:
0: iconst_0 //-将int类型的0推送到栈顶
1: istore_2 //-将栈顶int型数值存入第三个本地变量 r
2: iconst_0 //-将int型0推送至栈顶
3: istore_3 //-将栈顶int型数值存入第四个本地变量 i
4: iload_3 //-将第四个int型本地变量推送至栈顶
5: iload_1 //-将第二个int型本地变量推送至栈顶
6: if_icmpge 18 //-比较栈顶两int型数值大小,当结果大于等于0时跳转
9: iinc 2, 1 //-将指定int型变量增加指定值
12: iinc 3, 1 //-将指定int型变量增加指定值
15: goto 4 //-无条件跳转
18: iload_2 //-将第四个int型本地变量推送至栈顶
19: ireturn //-返回一个int值
}
“//-”是我自己写的注释
在此只关注method方法
4.按照上面的字节码文件编写java代码如下:
package club.jiajia.test3;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class TestAsm4 implements Opcodes{
public static void main(String[] args) throws InstantiationException, IllegalAccessException{
ClassWriter cw=new ClassWriter(0);
String className="Example4";
cw.visit(0x31,ACC_PUBLIC,className,null,"java/lang/Object",new String[]{"java/lang/Cloneable",ITest.class.getName().replace('.','/')});
String method="method";
MethodVisitor mv;
/***********************************************************/
Label end = new Label();
mv=cw.visitMethod(ACC_PUBLIC,method,"(I)I",null,null);
mv.visitCode();
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE,2);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE,3);
Label f=new Label();
mv.visitLabel(f);
mv.visitFrame(F_SAME, 0, null, 0, null);
mv.visitVarInsn(ILOAD,3);
mv.visitVarInsn(ILOAD,1);
mv.visitJumpInsn(IF_ICMPGE, end);
mv.visitIincInsn(2,1);
mv.visitIincInsn(3,1);
mv.visitJumpInsn(GOTO, f);
mv.visitLabel(end);
mv.visitFrame(F_SAME, 0, null, 0, null);
mv.visitVarInsn(ILOAD,2);
mv.visitInsn(IRETURN);
mv.visitMaxs(2, 4);
mv.visitEnd();
/***********************************************************/
//下面产生构造方法
mv=cw.visitMethod(ACC_PUBLIC,"<init>","()V",null,null);
mv.visitCode();
mv.visitVarInsn(ALOAD,0);
mv.visitMethodInsn(INVOKESPECIAL,"java/lang/Object","<init>","()V");
mv.visitInsn(RETURN);
mv.visitMaxs(1,1);
mv.visitEnd();
cw.visitEnd();
byte[] bs=cw.toByteArray();
File file = new File("E://jiajiajia/Example4.class");
try {
FileOutputStream fout = new FileOutputStream(file);
fout.write(bs);
fout.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
MyCLassLoader loader=new MyCLassLoader();
Class<?> c=loader.defineClass(bs);
ITest ins=(ITest)c.newInstance();
System.out.println(ins.method(123));
}
public interface ITest{
public int method(int a);
}
public static class MyCLassLoader extends ClassLoader{
public Class<?> defineClass(byte[] data){
return super.defineClass(null,data,0,data.length,null);
}
}
}
5.反编译生成的class文件如下:
评论区
请写下您的评论...
猜你喜欢
blog
asm生成switch语句方法
java基础
2642
1.jar包:2.原java文件:packageclub.jiajia.test3;publicclassExamp3{ publicintmethod(inta){ switch(a){ case123: a=1230; break; case128: a=1280; break; case12: a=120; break; } returna
java基础
3929
asm动态生成类和getandset方法1.自定义类加载器packageclub.jiajia.test;publicclassMyClassLoaderextendsClassLoader
blog
asm实例对象方法的调用
java基础
3215
asm实例对象方法的调用1.需要的jar包2.我们需要通过asm生成的目标类如下:packageclub.jiajia.test3;publicclassExamp5
数据库基础
2380
两种用法:简单case函数casesexwhen'1'then'男'when'2'then'女’else'其他'endcase搜索函数casewhensex='1'then'男'whensex='2
blog
java中有没有goto关键字
java基础
1463
,跳出循环体等功能。而在结构化程序语言中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难。但是在java语言中,goto这个词只是作为了保留字,还没有使用。那是因为java语
数据结构与算法
1828
约瑟夫环问题描述有m个人,围成一个环,编号为1、2、3、、、m,从第一个人开始循环报数(从1开始数),假设数到n的那个人出局,然后从下一个人继续数数(从1开始数),数到n出列,以此循环,最后那个人为
weblog
2470
java使用原生jdbc连接数据库获取数据或执行sql语句(mysql) publicvoidtest2(){ try{ //加载MySql的驱动类 Class.forName
blog
mysql批量更新生成不同的uuid
数据库
2757
mysql批量更新生成不同的uuidsql语句:UPDATEusersetuuid=UUID();去掉中间的-UPDATEusersetuuid=REPLACE(uuid,"-","");注意这两个
最新发表
归档
2018-11
12
2018-12
33
2019-01
28
2019-02
28
2019-03
32
2019-04
27
2019-05
33
2019-06
6
2019-07
12
2019-08
12
2019-09
21
2019-10
8
2019-11
15
2019-12
25
2020-01
9
2020-02
5
2020-03
16
2020-04
4
2020-06
1
2020-07
7
2020-08
13
2020-09
9
2020-10
5
2020-12
3
2021-01
1
2021-02
5
2021-03
7
2021-04
4
2021-05
4
2021-06
1
2021-07
7
2021-08
2
2021-09
8
2021-10
9
2021-11
16
2021-12
14
2022-01
7
2022-05
1
2022-08
3
2022-09
2
2022-10
2
2022-12
5
2023-01
3
2023-02
1
2023-03
4
2023-04
2
2023-06
3
2023-07
4
2023-08
1
2023-10
1
2024-02
1
2024-03
1
2024-04
1
2024-08
1
标签
算法基础
linux
前端
c++
数据结构
框架
数据库
计算机基础
储备知识
java基础
ASM
其他
深入理解java虚拟机
nginx
git
消息中间件
搜索
maven
redis
docker
dubbo
vue
导入导出
软件使用
idea插件
协议
无聊的知识
jenkins
springboot
mqtt协议
keepalived
minio
mysql
ensp
网络基础
xxl-job
rabbitmq
haproxy
srs
音视频
webrtc
javascript
加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。