# dyASMTop **Repository Path**: jaciyu/dyASMTop ## Basic Information - **Project Name**: dyASMTop - **Description**: 封装asm生成字节码工具 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2018-01-18 - **Last Updated**: 2021-11-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # dyASMTop ## 介绍 该工具包是学习redkale字节码部分的衍生工具包。 asm使用比较麻烦,此jar包是封装asm直接生成字节码对象的工具 ## 开发环境 > - jdk1.8 + maven > - jdk内置asm + GeneratorAdapter方式 ## 开发记录 大概差不多的情况下会进行完整示例的编码 > - 2018-01-15 生成基本的骨架代码,把字节码指令抽象为command准备实现 > - 2018-01-15 完成参数调用arg和方法调用call指令 > - 2018-01-16 完成field属性获取方法 > - 2018-01-16 完成临时变量的获取local > - 2018-01-16 完成定义临时变量的let方法 > - 2018-01-16 完成调用类构造函数的方法 > - 2018-01-16 完成比较类方法 > - 2018-01-16 完成if...else方法 > - 2018-01-16 增加注解回调方法功能 > - 2018-01-17 增加四则运算方法 > - 2018-01-17 增加调用super方法callSuper(只能调用mainClass中的方法) > - 2018-01-17 增加调用外部类静态方法callStatic > - 2018-01-17 增加调用静态方法callStaticSelf > - 2018-01-17 增加for i方法 > - 2018-01-17 ClassBuilder增加buildInstance返回对象实例方法 > - 2018-01-17 增加数组new,get,set,length操作 > - 2018-01-17 增加map循环操作 > - 2018-01-17 增加数组,集合循环操作 > - 2018-01-17 修改super调用方式,在不传入方法名和参数情况下,默认为在重载方法中直接调用父类对应的方法 > - 2018-01-17 增加获取其他对象静态字段的方法fieldStatic ## 简单示例 ##### TestCall.java > ``` > public class TestCall { > > public int add(int a, int b) { > return a + b; > } > > } > ``` ##### TestCall3.java > ``` > public class TestCall3 { > > public int add(int a, int b) { > return a + b + 12; > } > } > ``` ##### TestClassAn.java > ``` > @Inherited > @Documented > @Target({TYPE}) > @Retention(RUNTIME) > public @interface TestClassAn { > > String name(); > > String value(); > } > ``` ##### ASMTopTest.java > ``` > public class ASMTopTest { > > public interface Test { > int add(int a, int b); > > int addif(int a, int b); > > int addArray(TestCall2 call2, int... array); > } > > public class TestCall2 { > public int add2(int a, int b) { > return a + b; > } > > public int addArray(int... arrays) { > return 0; > } > } > > public static void main(String[] args) throws Exception { > File file = new File(""); > Path currentPath = file.toPath(); > > Class testClass = ClassBuilder.create(ASMClassLoader.create(), Test.class) > .savePath(currentPath) > .withAnnotation((cw)->{ > AnnotationVisitor av0 = cw.visitAnnotation(Type.getDescriptor(TestClassAn.class), true); > av0.visit("name", "测试注解类"); > av0.visit("value", "测试值"); > av0.visitEnd(); > }) > .addField("x", int.class) > .addField("y", Long.class) > .addMethod("add", ((WithValue) () -> { > CommandSequence sequence = CommandSequence.create(); > Variable pojo = CB.let(CB.constructor(TestCall.class)); > sequence.add(CB.call(pojo, "add", CB.arg(0), CB.arg(1))); > return sequence; > }).get()) > .addMethod("addArray", CB.call(CB.arg(0), "addArray", CB.arg(1))) > .addMethod("addif", CB.ifThenElse( > CB.ge(CB.arg(0), CB.value(1)), > > ((WithValue) () -> { > CommandSequence sequence = CommandSequence.create(); > Variable pojo = CB.let(CB.constructor(TestCall.class)); > sequence.add(CB.call(pojo, "add", CB.arg(0), CB.arg(1))); > return sequence; > }).get(), > > ((WithValue) () -> { > CommandSequence sequence = CommandSequence.create(); > Variable pojo = CB.let(CB.constructor(TestCall3.class)); > sequence.add(CB.call(pojo, "add", CB.arg(0), CB.arg(1))); > return sequence; > }).get())) > .build(); > } > } > ``` ##### 反编译保存的class文件后的效果 ![image](https://gitee.com/jlutt/dyASMTop/raw/master/%E5%8F%8D%E7%BC%96%E8%AF%91.png) ## 参考实现 > 1. [redkale](https://github.com/redkale/redkale) > 1. [asmsupport](https://github.com/wensiqun/asmsupport) > 1. [datakernel](https://github.com/softindex/datakernel)