asm基础学习1
本文给出一个最简单的通过asm生成一个java类的例子:
?
生成这样一个类:
public class TestDzl { private String name; public void sayHello(String s){ System.out.print("welcome, "); System.out.println(s); name="zili.dengzl"; } public void printName(){ System.out.println(name); }}
生成代码如下:
import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import com.alibaba.ITestDzl;public class AsmLearn1 implements Opcodes { /** * @param args */ public static void main(String[] args) { byte[] clazzBytes = generateClass(); printClass(clazzBytes); Class<?> clazz = loadClass(clazzBytes); callByInterface(clazz); callByReflect(clazz); } private static void callByReflect(Class<?> clazz) { try { Constructor<?> cns = clazz.getConstructor(); Object o = cns.newInstance(); System.out.printf("%s","sayHello:"); Method method = clazz.getMethod("sayHello", String.class); method.invoke(o, "callByReflect"); System.out.printf("%s","printName:"); Method method2 = clazz.getMethod("printName"); method2.invoke(o); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void callByInterface(Class<?> clazz) { try { Object o = clazz.newInstance(); System.out.println(o); ITestDzl t = (ITestDzl) o; t.sayHello("callByInterface"); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static Class<?> loadClass(byte[] clazzBytes) { Class<?> clazz = new ClassLoader(AsmLearn1.class.getClassLoader()) { public Class<?> loadClassFromBytes(String name, byte[] b) { return defineClass(name, b, 0, b.length); } }.loadClassFromBytes("TestDzl", clazzBytes); return clazz; } private static byte[] generateClass() { ClassWriter cw = new ClassWriter(); cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, "TestDzl", "java/lang/Object", new String[]{"com/alibaba/ITestDzl"}); FieldVisitor fv = cw.visitField(ACC_PRIVATE, "name", "Ljava/lang/String;"); fv.visitEnd(); // 初始化方法 MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mw.visitVarInsn(ALOAD, 0); mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mw.visitInsn(RETURN); mw.visitMaxs(1, 1); mw.visitEnd(); // sayHello方法 MethodVisitor mw2 = cw.visitMethod(ACC_PUBLIC, "sayHello", "(Ljava/lang/String;)V", null, null); mw2.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mw2.visitLdcInsn("welcome, "); mw2.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V"); mw2.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mw2.visitVarInsn(ALOAD, 1); mw2.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); mw2.visitVarInsn(ALOAD, 0); mw2.visitLdcInsn("zili.dengzl"); mw2.visitFieldInsn(PUTFIELD, "TestDzl", "name", "Ljava/lang/String;"); mw2.visitMaxs(2, 2); mw2.visitInsn(RETURN); mw2.visitEnd(); //printName()方法 MethodVisitor mw3 = cw.visitMethod(ACC_PUBLIC, "printName", "()V", null, null); mw3.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mw3.visitVarInsn(ALOAD, 0); mw3.visitFieldInsn(GETFIELD, "TestDzl", "name", "Ljava/lang/String;"); mw3.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); mw3.visitMaxs(2, 2); mw3.visitInsn(RETURN); mw3.visitEnd(); byte[] clazzBytes = cw.toByteArray(); return clazzBytes; } private static void printClass(byte[] clazzBytes) { try { FileOutputStream fos = new FileOutputStream("d:/TestDzl.class"); fos.write(clazzBytes); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(clazzBytes); }}