简介

类似字节码操作方法还有ASM。几种动态编程方法相比较,在性能上Javassist高于反射,但低于ASM,因为Javassist增加了一层抽象。在实现成本上Javassist和反射都很低,而ASM由于直接操作字节码,相比Javassist源码级别的api实现成本高很多。几个方法有自己的应用场景,比如Kryo使用的是ASM,追求性能的最大化。而NBeanCopyUtil采用的是Javassist,在对象拷贝的性能上也已经明显高于其他的库,并保持高易用性。实际项目中推荐先用Javassist实现原型,若在性能测试中发现Javassist成为了性能瓶颈,再考虑使用其他字节码操作方法做优化。

ASM 是一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

不过ASM在创建class字节码的过程中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解。

JavaAssist和Asm都是一种在运行时,修改字节码的框架,如下图所示

JavaAssit和Asm的核心类:

  • ClassWriter
  • MethodVisitor

JavaAssit的核心类:

  • ClassPool
  • CtClass
  • CtMethod

示例

ASM:采用适配模式修改类

public class TestAsm {

    public static void main(String[] args) throws IOException {
ClassReader classReader = new ClassReader("com.longchao.asm.TestClass");
ClassWriter classWriter = new ClassWriter(classReader, 0);
ClassVisitor classVisitor = new ProgrammerClassAdapter(classWriter);
classReader.accept(classVisitor, 0); }
} public class ProgrammerClassAdapter extends ClassAdapter{
public ProgrammerClassAdapter(ClassVisitor classVisitor) {
super(classVisitor);
}
public MethodVisitor visitMethod(int access,String name,String desc,String signature,String[] exceptions){
MethodVisitor methodVisitor = cv.visitMethod(access,name,desc,signature,exceptions);
if(null != methodVisitor&& "doCoding".equals(name)){
methodVisitor = new DoCodingMethodAdapter(methodVisitor);
return methodVisitor; }
return methodVisitor;
}
} public class DoCodingMethodAdapter extends MethodAdapter { public DoCodingMethodAdapter(MethodVisitor arg0){
super(arg0);
} public void visitCode(){
super.visitCode();
mv.visitFieldInsn(Opcodes.GETSTATIC,"System","out","Ljava/io/PrintStream");
mv.visitLdcInsn("doAsmCode............");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V"); } }

JavaAssit的示例

public class TestJavaAssist {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
//创建Programmer类
CtClass cc= pool.makeClass("com.longchao.Programmer");
//定义code方法
CtMethod method = CtNewMethod.make("public void code(){}", cc);
//插入方法代码
method.insertBefore("System.out.println(\"I'm a Programmer,Just Coding.....\");");
cc.addMethod(method);
//保存生成的字节码
cc.writeFile("d://temp");
}
}

最新文章

  1. ios10.2真机调试包,ios升级10.2后需要添加
  2. [LeetCode] Remove Duplicates from Sorted Array II 有序数组中去除重复项之二
  3. Oracle常用SQL查询(2)
  4. mmap DMA【转】
  5. android学习笔记32——资源
  6. 达内TTS6.0课件oop_day02
  7. CMMI 是什么东西?
  8. css 初始化
  9. 适配器模式及C++实现
  10. 七个 Android 程序猿提高效率必备工具
  11. oracle session数激增排查过程
  12. Android(Lollipop/5.0) Material Design(二) 入门指南
  13. Android--性能测试关注的指标
  14. SLAM+语音机器人DIY系列:(三)感知与大脑——4.音响麦克风与摄像头
  15. laravel整合workerman做消息推送系统
  16. Node.js 安装与管理
  17. android面试题总结加强再加强版(一)
  18. JAVA面对对象(五)——接口
  19. jquery zTree异步搜索的例子--搜全部节点
  20. BZOJ.1923.[SDOI2010]外星千足虫(高斯消元 异或方程组 bitset)

热门文章

  1. Nginx redirect
  2. C#第十三天
  3. 分子量(Molar Mass,ACM/ICPC Seoul 2007,UVa 1586)
  4. 找出Java数组中不同的值
  5. Mybatis的传参
  6. css的三大特性
  7. 信息存储——当值X是2的非负整数n次幂时,如何表示成十六进制
  8. 快速挂载和分离VHD文件的小脚本
  9. Ubuntu 14.0 升级内核到指定版本
  10. CodeForces 702B Powers of Two