博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
asm-3.3.1.jar详解 (转)
阅读量:7215 次
发布时间:2019-06-29

本文共 3451 字,大约阅读时间需要 11 分钟。

Java字节码操纵框架。它可以直接以二进制形式动态地生成stub类或其他代理类,或者在装载时动态地修改类。ASM提供类似于BCEL和SERP之类的工具包的功能,但是被设计得更小巧、更快速,这使它适用于实时代码插装。
.NET/liyangbing315/article/details/5472862
你可以利用ASM动态操作class

 

我们知道Java是静态语言,而ruby是动态语言,Java程序一旦写好很难在运行时更改类的行为,而、ruby可以。 

不过基于bytecode层面上我们可以做一些手脚,来使Java程序多一些灵活性和Magic,ASM就是这样一个应用广泛的开源库。 
ASM is a Java bytecode manipulation framework. It can be used to dynamically generatestub classes or other proxy classes, 
directly in binary form, or to dynamically modify classes at load time, i.e., justbefore they are loaded into the Java 
Virtual Machine. 
ASM完成了和同样的功能,但ASM 
只有30多k,而后两者分别是350k和150k。apache真是越来越过气了。 
让我们来看一个ASM的简单例子Helloworld.java,它生成一个Example类和一个main方法,main方法打印"Hello world!"语句:

Java代码

  1. import java.io.FileOutputStream;   
  2. import java.io.PrintStream;   
  3.   
  4. import org.objectweb.asm.ClassWriter;   
  5. import org.objectweb.asm.MethodVisitor;   
  6. import org.objectweb.asm.Opcodes;   
  7. import org.objectweb.asm.Type;   
  8. import org.objectweb.asm.commons.GeneratorAdapter;   
  9. import org.objectweb.asm.commons.Method;   
  10.   
  11. public class Helloworld extends ClassLoader implements Opcodes {   
  12.   
  13.   public static void main(final String args[]) throws Exception {   
  14.   
  15.     // creates a ClassWriter for the Example public class,   
  16.     // which inherits from Object   
  17.   
  18.      ClassWriter cw = new ClassWriter(0);   
  19.      cw.visit(V1_1, ACC_PUBLIC, "Example", null"java/lang/Object", null);   
  20.      MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,   
  21.         null);   
  22.      mw.visitVarInsn(ALOAD, 0);   
  23.      mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");   
  24.      mw.visitInsn(RETURN);   
  25.      mw.visitMaxs(1, 1);   
  26.      mw.visitEnd();   
  27.      mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",   
  28.         "([Ljava/lang/String;)V", nullnull);   
  29.      mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",   
  30.         "Ljava/io/PrintStream;");   
  31.      mw.visitLdcInsn("Hello world!");   
  32.      mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",   
  33.         "(Ljava/lang/String;)V");   
  34.      mw.visitInsn(RETURN);   
  35.      mw.visitMaxs(2, 2);   
  36.      mw.visitEnd();   
  37.     byte[] code = cw.toByteArray();   
  38.      FileOutputStream fos = new FileOutputStream("Example.class");   
  39.      fos.write(code);   
  40.      fos.close();   
  41.      Helloworld loader = new Helloworld();   
  42.      Class exampleClass = loader   
  43.          .defineClass("Example", code, 0, code.length);   
  44.      exampleClass.getMethods()[0].invoke(nullnew Object[] { null });   
  45.   
  46.     // ------------------------------------------------------------------------   
  47.     // Same example with a GeneratorAdapter (more convenient but slower)   
  48.     // ------------------------------------------------------------------------   
  49.   
  50.      cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);   
  51.      cw.visit(V1_1, ACC_PUBLIC, "Example", null"java/lang/Object", null);   
  52.      Method m = Method.getMethod("void <init> ()");   
  53.      GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, nullnull,   
  54.          cw);   
  55.      mg.loadThis();   
  56.      mg.invokeConstructor(Type.getType(Object.class), m);   
  57.      mg.returnValue();   
  58.      mg.endMethod();   
  59.      m = Method.getMethod("void main (String[])");   
  60.      mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, nullnull, cw);   
  61.      mg.getStatic(Type.getType(System.class), "out", Type   
  62.          .getType(PrintStream.class));   
  63.      mg.push("Hello world!");   
  64.      mg.invokeVirtual(Type.getType(PrintStream.class), Method   
  65.          .getMethod("void println (String)"));   
  66.      mg.returnValue();   
  67.      mg.endMethod();   
  68.      cw.visitEnd();   
  69.      code = cw.toByteArray();   
  70.      loader = new Helloworld();   
  71.      exampleClass = loader.defineClass("Example", code, 0, code.length);   
  72.      exampleClass.getMethods()[0].invoke(nullnew Object[] { null });   
  73.    }   
  74. }  

我们看到上面的例子分别使用ASM的MethodVisitor和GeneratorAdapter两种方式来动态生成Example类并调用打印语句。

转载于:https://www.cnblogs.com/Syria/p/6551286.html

你可能感兴趣的文章
Ceylon语言加入Eclipse基金会
查看>>
一文盘点MWC 2019所有5G设备和研发进展
查看>>
【leetcode】85. Maximal Rectangle 0/1矩阵的最大全1子矩阵
查看>>
网站真分页js代码该怎么写?
查看>>
教你五分钟入门使用html5 svg绘制图形
查看>>
vue-concise-slider vue滑动组件
查看>>
ElectronOCR:基于Electron+React+Tesseract的MACOS下的OCR工具
查看>>
Mysql 架构及优化之-定时计划任务
查看>>
不插即用!配备微信网页授权模块的CodeIgniter应用脚手架
查看>>
HBase存储剖析与数据迁移
查看>>
人工智能高考511分,未来有望考上东京大学!
查看>>
O2O业务都跳不出这五大领域
查看>>
呼之欲出的量子计算机和漫长的最后一公里
查看>>
“九”答不可 | 量子保密,完美无缺?
查看>>
VMware备份研究
查看>>
dotnet调用node.js写的socket服务(websocket/socket/socket.io)
查看>>
Nibiru Open Day,OZO 遇见 DigiArtist 国际数字艺术展
查看>>
MySQL · 引擎分析 · InnoDB行锁分析
查看>>
ARKit应用超300万次安装,排第一的是一款养成游戏
查看>>
C++ 对引用的深入理解
查看>>