asmsupport實在asm的基礎上做的一封裝,使用asmsupport將最大限度的降低位元組碼操作的成本,禁止了使用asm的時候對堆疊操作,以及原生的位元組碼指令。
基本介紹
- 中文名:ASM支持類庫
- 外文名:ASMSupport
- 最新版本:0.4
- 描述:一個java位元組碼操作類庫
概述,ASM&ASMSupport對比,Java源,ASM代碼,ASMSupport代碼,資源,
概述
同時增加了更多的靈活性,採用匿名類的方式使方法塊更清晰。
ASM&ASMSupport對比
這裡我們簡單的使用asm和asmsupport來生成如下代碼:
Java源
public class Test { public static void main(String name) { System.out.println("Hello : " + name); }}
ASM代碼
1. ClassWriter mv = cw.visitMethod(Opcodes.ACCpublic_ + Opcodes.ACC_STATIC, "main", "(Ljava/lang/String;)V", null, null);2. mv.visitCode();3. Label l0 = new Label();4. mv.visitLabel(l0);5. mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");6. mv.visitTypeInsn(NEW, "java/lang/StringBuilder");7. mv.visitInsn(DUP);8. mv.visitLdcInsn("Hello : ");9. mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false);10. mv.visitVarInsn(ALOAD, 0);11. mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);12. mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);13. mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);14. Label l1 = new Label();15. mv.visitLabel(l1);16. mv.visitInsn(RETURN);17. Label l2 = new Label();18. mv.visitLabel(l2);19. mv.visitLocalVariable("name", "Ljava/lang/String;", null, l0, l2, 0);20. mv.visitMaxs(4, 1);21. mv.visitEnd();22. cw.visitEnd();23. byte[] classBytes = cw.toByteArray()
從上面可以看到我們想要創建一個class不僅需要使用複雜的位元組碼指令(比如第5,6,9…行),而且還要關注堆疊操作(比如第10行就是從局部變數中獲取第0個位置,就是方法的參數name),同時在最後需要確定好方法所需要的堆疊數目(第20行)。對一些隱式的方法位元組碼還需特殊處理,比如第6~12行的代碼對應的就是(“Hello : ” + name),但實際根據位元組碼生成的內容實際是調用了new StringBuilder(“Hello : ”).append(name).toString().這樣就大大的增加了開發難度。
ASMSupport代碼
DummyClass dc = new DummyClass().public_().name("TestCommon").setClassOutPutPath(".//target//dummy-generated");dc.newMethod("main").public_().static_() .argTypes(String.class).argNames_("name") .body_(new MethodBody(){ @Override public void body(LocalVariable... args) { call_(defType(System.class).field("out"), "println", stradd(val("Hello : "), args[0])); return_(); } });Class cls = dc.build();
資源
maven坐標:
<dependency> <groupId>cn.wensiqun</groupId> <artifactId>asmsupport</artifactId> <version>0.4</version> </dependency>