概述
一、什么是ASM
ASM是一个JAVA字节码分析、创建和修改的开源应用框架。在ASM中提供了诸多的API用于对类的内容进行字节码操作的方法。与传统的BCEL和SERL不同,在ASM中提供了更为优雅和灵活的操作字节码的方式。目前ASM已被广泛的开源应用架构所使用,例如:Spring、Hibernate等。
二、ASM能干什么
分析一个类、从字节码角度创建一个类、修改一个已经被编译过的类文件
三、ASM初探例子
通过字节码实现
public class Example {
public static void main(String[] args) {
int a = 6;
int b = 7;
int c = (a + b) * 3;
System.out.println(c);
}
}
实现代码如下:
package com.jvm.day8.asm;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* 用asm生成字节码
*
* @Author:xuehan
* @Date:2016年4月2日下午6:13:23
*/
public class ASMHelloWorld extends ClassLoader {
public static void main(String[] args) throws Exception {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, "com/jvm/day8/asm/Example", null, "java/lang/Object", null);
// 方法开始init
MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mw.visitVarInsn(Opcodes.ALOAD, 0); // this 入栈
mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mw.visitInsn(Opcodes.RETURN);
mw.visitMaxs(0, 0);
mw.visitEnd(); // 方法init结束
// main方法开始
mw = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
/**
* 使用ASM,通过字节码 完成以下代码: int a=6; int b=7; int c=(a+b)*3;
* System.out.println(c);
*/
// 把变量放入局部变量表里
mw.visitIntInsn(Opcodes.BIPUSH, 6);
mw.visitVarInsn(Opcodes.ISTORE, 3);
mw.visitIntInsn(Opcodes.BIPUSH, 7);
mw.visitVarInsn(Opcodes.ISTORE, 4);
// 操作数栈
mw.visitVarInsn(Opcodes.ILOAD, 3);
mw.visitVarInsn(Opcodes.ILOAD, 4);
mw.visitInsn(Opcodes.IADD);
mw.visitIntInsn(Opcodes.BIPUSH, 3);
mw.visitInsn(Opcodes.IMUL);
mw.visitVarInsn(Opcodes.ISTORE, 2);
// 打印出来
mw.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mw.visitVarInsn(Opcodes.ILOAD, 2);
mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V");
mw.visitInsn(Opcodes.RETURN);
mw.visitMaxs(0, 0);
mw.visitEnd(); // main方法结束
final byte[] code = cw.toByteArray();
ASMHelloWorld loader = new ASMHelloWorld();
Class<?> exampleClass = loader.defineClass("com.jvm.day8.asm.Example", code, 0, code.length);
exampleClass.getMethods()[0].invoke(null, new Object[] { null });
}
}
最后
以上就是落后耳机为你收集整理的jvm第9节-asm生成class字节码的全部内容,希望文章能够帮你解决jvm第9节-asm生成class字节码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复