asm生成switch语句方法

硅谷探秘者 2421 0 0

1.jar包:

menu.saveimg.savepath20190322113852.jpg

2.原java文件:

package club.jiajia.test3;
public class Examp3 {
	public int method(int a){
		switch (a) {
			case 123:
			    a=1230;
				break;
			case 128:
				a=1280;
				break;
			case 12:
				a=120;
				break;
		}
		return a;
	}
}

3.javap -c命令反编译此java的字节码文件

Compiled from "Examp3.java"
public class club.jiajia.test3.Examp3 {
  public club.jiajia.test3.Examp3();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public int method(int);
    Code:
       0: iload_1
       1: lookupswitch  { // 3

                    12: 50

                   123: 36

                   128: 43
               default: 53
          }
      36: sipush        1230
      39: istore_1
      40: goto          53
      43: sipush        1280
      46: istore_1
      47: goto          53
      50: bipush        120
      52: istore_1
      53: iload_1
      54: ireturn
}

    我们只看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 TestAsm3 implements Opcodes{
	public static void main(String[] args) throws InstantiationException, IllegalAccessException{
		ClassWriter cw=new ClassWriter(0);
		String className="Example3";
		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.visitVarInsn(ILOAD, 1);
		Label def=new Label();
		int val[]=new int[]{12,123,128};
		Label labs[]=new Label[3];
		labs[0]=new Label();
		labs[1]=new Label();
		labs[2]=new Label();
		mv.visitLookupSwitchInsn(def,val,labs);
		
		mv.visitLabel(labs[0]);
		mv.visitFrame(F_SAME, 0, null, 0, null);
		mv.visitIntInsn(SIPUSH,1230);
		mv.visitVarInsn(ISTORE,1);
		mv.visitJumpInsn(GOTO, end);
		
		mv.visitLabel(labs[1]);
		mv.visitFrame(F_SAME, 0, null, 0, null);
		mv.visitIntInsn(SIPUSH,1280);
		mv.visitVarInsn(ISTORE,1);
		mv.visitJumpInsn(GOTO, end);
		
		mv.visitLabel(labs[2]);
		mv.visitFrame(F_SAME, 0, null, 0, null);
		mv.visitIntInsn(SIPUSH,120);
		mv.visitVarInsn(ISTORE,1);
		mv.visitJumpInsn(GOTO, end);
		
		mv.visitLabel(def);
		mv.visitFrame(F_SAME, 0, null, 0, null);
		
		mv.visitLabel(end);
		mv.visitFrame(F_SAME, 0, null, 0, null);
		
		mv.visitVarInsn(ILOAD, 1);
		mv.visitInsn(IRETURN);
		mv.visitMaxs(2, 2);
		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/Example3.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(12003));
	}
	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文件如下:

menu.saveimg.savepath20190322113629.jpg




评论区
请写下您的评论...
暂无评论...
猜你喜欢
java基础 2324 asmfor循环1.jar包2.原java文件packageclub.jiajia.test3;publicclassExamp4{ publicintmethod(inta
java基础 3582 asm动态类和getandset1.自定义类加载器packageclub.jiajia.test;publicclassMyClassLoaderextendsClassLoader
java基础 2935 asm实例对象的调用1.需要的jar包2.我们需要通过asm的目标类如下:packageclub.jiajia.test3;publicclassExamp5
数据库基础 2162 两种用:简单case函数casesexwhen'1'then'男'when'2'then'女’else'其他'endcase搜索函数casewhensex='1'then'男'whensex='2
weblog 2127 java使用原jdbc连接数据库获取数据或执行sql(mysql) publicvoidtest2(){ try{ //加载MySql的驱动类 Class.forName
数据库 2429 mysql批量更新不同的uuidsql:UPDATEusersetuuid=UUID();去掉中间的-UPDATEusersetuuid=REPLACE(uuid,"-","");注意这两个
weblog 675 冠词-英
数据结构与算法 1500 prim(普里姆)算求出。对于任何一个数据结构或算,理解和实现只是一个面,更重要的是要明白它的应用范围或应用场景,最小树算的应用非常广泛,例如:假设要在n个城市之间建立通信联络网,则连接n个
归档
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
标签
算法基础 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
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。