「调用外部」【开发者成长】如果你只写CRUD,那这种技术栈你永远碰不到( 二 )
private static byte[] generate() {
ClassWriter classWriter = new ClassWriter(0); // 定义对象头;版本号、修饰符、全类名、签名、父类、实现的接口 classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, ''org/itstack/demo/asm/AsmHelloWorld'', null, ''java/lang/Object'', null); // 添加方法;修饰符、方法名、描述符、签名、异常 MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, ''main'', ''([Ljava/lang/String;)V'', null, null); // 执行指令;获取静态属性 methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, ''java/lang/System'', ''out'', ''Ljava/io/PrintStream;''); // 加载常量 load constant methodVisitor.visitLdcInsn(''Hello World''); // 调用方法 methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, ''java/io/PrintStream'', ''println'', ''(Ljava/lang/String;)V'', false); // 返回 methodVisitor.visitInsn(Opcodes.RETURN); // 设置操作数栈的深度和局部变量的大小 methodVisitor.visitMaxs(2, 1); // 方法结束 methodVisitor.visitEnd(); // 类完成 classWriter.visitEnd(); // 生成字节数组 return classWriter.toByteArray(); }
以上的代码,“小朋友,你是否有很多问好???^1024”,其实以上的代码都是来自于 ASM 框架的代码,这里面所有的操作与我们使用使用 javap -c XXX 所反解析出的字节码是一样的,只不过是反过来使用指令来编写代码。
1.定义一个类的生成 ClassWriter
2.设定版本、修饰符、全类名、签名、父类、实现的接口,其实也就是那句;public class HelloWorld
3.接下来开始创建方法,方法同样需要设定;修饰符、方法名、描述符等。这里面有几个固定标识;

文章图片
4.执行指令;获取静态属性。主要是获得 System.out
5.加载常量 load constant,输出我们的HelloWorld methodVisitor.visitLdcInsn(''Hello World'');
6.最后是调用输出方法并设置空返回,同时在结尾要设置操作数栈的深度和局部变量的大小
这样输出一个 HelloWorld 是不还是蛮有意思的,虽然你可能觉得这编码起来实在太难了吧,也非常难理解。首先如果你看过我的专栏,用《Java写一个Jvm虚拟机》,那么你可能会感受到这里面的知识点还是不那么陌生的。另外这里的编写,ASM还提供了插件,可以方便的让你开发字节码。接下来就介绍一下使用方式。
五、有插件的帮助字节码开发也不是很难
对于新人来说如果用字节码增强开发一些东西确实挺难,尤其是一些复杂的代码块使用字节码指令操作还是很有难度的。那么,其实也是有简单办法就是使用 ASM 插件。这个插件可以很轻松的让你看到一段代码的指令码以及如何用ASM去开发。
1.安装插件(ASM Bytecode Outline)

文章图片
2.测试使用

文章图片
是不是看到有插件的帮助下,心里有所激动了,至少写这样的东西有了抓手。这样你就可以很方便的去操作一些增强字节码的功能了。
六、用字节码写出一个两数之和计算
好!有了上面的插件,也有了一些基础知识的了解。那么我们开发一个计算两数之和的方法,之后运行计算结果。
这是我们的目标
使用字节码编程方式实现
- 上面有两个括号 {},第一个是用于生成一个空的构造函数
- 接下来的指令就比较简单了,首先使用 ILOAD 进行数值的两次压栈也就是弄到操作数栈里去操作,接下来开始执行 IADD,将两数相加。
推荐阅读
- 特斯拉|特斯拉或将允许车主远程调用Autopilot摄像头
- 内置于APP程序内的广告,SDK广告的市场前景怎样,如有媒介的话,APP程序开发者.媒介.广告商咋分成的
- 如果你是AppStore的工作人员,你想咋帮助中国区的开发者列举你最想做的2件事情
- 参见Esri开发者大会是一种咋样的体验
- 国内Android个人开发者的应用怎样收费
- webpack打包后的页面,在集成时,怎样提供js接口给父页面调用呢
- javascript 中this的四种调用模式
- C语言多维数组声明调用和c为啥差别这么大
- 阿贵看车|专访|宋军:后千万时代,吉利汽车更强调用户体验
- macOS 用PHP调用curl抓取不到https的数据
