Skip to content

Instantly share code, notes, and snippets.

@liuxinglanyue
Last active June 27, 2016 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liuxinglanyue/430ba68a4123e3e0eddfe228bd2187cf to your computer and use it in GitHub Desktop.
Save liuxinglanyue/430ba68a4123e3e0eddfe228bd2187cf to your computer and use it in GitHub Desktop.
内部类类名和父类类名相同的问题
public class B {
public static void main(String[] args) {
}
public class B {
public String d;
}
}
import org.objectweb.asm.*;
import java.io.FileOutputStream;
import java.io.IOException;
public class OuterClass extends ClassLoader implements Opcodes {
public static void main(final String args[]) throws Exception {
ClassWriter cw = new ClassWriter(0);
cw.visit(V1_1, ACC_PUBLIC, "A", null, "java/lang/Object", null);
cw.visitInnerClass("A$A", "A", "A", ACC_PUBLIC);
//生成默认的构造方法
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();
//生成main方法
mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
"main",
"([Ljava/lang/String;)V",
null,
null);
//生成main方法中的字节码指令
mw.visitFieldInsn(GETSTATIC,
"java/lang/System",
"out",
"Ljava/io/PrintStream;");
mw.visitLdcInsn("Hello world!");
mw.visitMethodInsn(INVOKEVIRTUAL,
"java/io/PrintStream",
"println",
"(Ljava/lang/String;)V");
//
mw.visitTypeInsn(Opcodes.NEW, "A");
mw.visitInsn(Opcodes.DUP);
mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "A", "<init>", "()V");
mw.visitVarInsn(ASTORE, 1);
mw.visitTypeInsn(Opcodes.NEW, "A$A");
mw.visitInsn(Opcodes.DUP);
mw.visitVarInsn(ALOAD, 1);
mw.visitInsn(Opcodes.DUP);
mw.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
mw.visitInsn(POP);
mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "A$A", "<init>", "(LA;)V");
mw.visitVarInsn(ASTORE, 2);
mw.visitVarInsn(ALOAD, 2);
mw.visitLdcInsn("e");
mw.visitFieldInsn(Opcodes.PUTFIELD, "A$A", "e", Type.getDescriptor(String.class));
mw.visitFieldInsn(GETSTATIC,
"java/lang/System",
"out",
"Ljava/io/PrintStream;");
mw.visitVarInsn(ALOAD, 2);
mw.visitFieldInsn(Opcodes.GETFIELD, "A$A", "e", Type.getDescriptor(String.class));
mw.visitMethodInsn(INVOKEVIRTUAL,
"java/io/PrintStream",
"println",
"(Ljava/lang/String;)V");
mw.visitInsn(RETURN);
mw.visitMaxs(4, 3);
//字节码生成完成
mw.visitEnd();
cw.visitEnd();
// 获取生成的class文件对应的二进制流
byte[] code = cw.toByteArray();
//将二进制流写到本地磁盘上
FileOutputStream fos = new FileOutputStream("A.class");
fos.write(code);
fos.flush();
fos.close();
//asm 写 内部类
byte[] outCode = out();
//直接将二进制流加载到内存中
OuterClass loader = new OuterClass();
Class<?> exampleClass = loader.defineClass("A", code, 0, code.length);
loader.defineClass("A$A", outCode, 0, outCode.length);
//通过反射调用main方法
exampleClass.getMethods()[0].invoke(null, new Object[] { null });
}
public static byte[] out() throws IOException {
//定义一个叫做Example的类
ClassWriter cw = new ClassWriter(0);
cw.visit(V1_1, ACC_PUBLIC, "A$A", null, "java/lang/Object", null);
FieldVisitor fv = cw.visitField(ACC_PUBLIC, "e", Type.getDescriptor(String.class), null, null);
fv.visitEnd();
FieldVisitor fv2 = cw.visitField(ACC_FINAL, "this$0", "LA;", null, null);
fv2.visitEnd();
//生成默认的构造方法
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC,
"<init>",
"(LA;)V",
null,
null);
//生成构造方法的字节码指令
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitFieldInsn(Opcodes.PUTFIELD, "A$A", "this$0", "LA;");
mw.visitVarInsn(ALOAD, 0);
mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mw.visitInsn(RETURN);
mw.visitMaxs(2, 2);
mw.visitEnd();
cw.visitEnd();
// 获取生成的class文件对应的二进制流
byte[] code = cw.toByteArray();
//将二进制流写到本地磁盘上
FileOutputStream fos = new FileOutputStream("A$A.class");
fos.write(code);
fos.flush();
fos.close();
return code;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment