ASM-00-java 字节码操作库入门教程
2016年5月21日大约 2 分钟
ASM
ASM is an all purpose Java bytecode manipulation and analysis framework. It can be used to modify existing classes or
dynamically generate classes, directly in binary form. Provided common transformations and analysis algorithms allow
to easily assemble custom complex transformations and code analysis tools.
complied class

Type descriptors
Java typeType descriptor
booleanZ
charC
shortS
intI
floatF
longJ
doubleD
ojbectLjava/lang/Object;
int[][I
Object[][][[Ljava/lang/Object;
Method descriptors
A method descriptor is a list of type descriptors that describe the parameter types and the return type of a method, in a single string.
Method declaration in sourceMethod descriptor
void m(int i, float f)(IF)V
int m(Object o)(Ljava/lang/Object;)I
int[] m(int i, String s)(ILjava/lang/String;)[I
Object m(int[] i)([I)Ljava/lang/Object;
Parsing classes
- The first step is to write a subclass of the ClassVisitor class that prints information about the classes it visits.
package com.asm;
import org.objectweb.asm.*;
import static jdk.internal.org.objectweb.asm.Opcodes.ASM4;
/**
* Created by houbinbin on 16/5/21.
*/
public class ClassPrinter extends ClassVisitor {
public ClassPrinter() {
super(ASM4);
}
public void visit(int version, int access, String name,
String signature, String superName, String[] interfaces) {
System.out.println(name + " extends " + superName + " {");
}
public void visitSource(String source, String debug) {
}
public void visitOuterClass(String owner, String name, String desc) {
}
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return null;
}
public void visitAttribute(Attribute attr) {
}
public void visitInnerClass(String name, String outerName,
String innerName, int access) {
}
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value) {
System.out.println(" " + desc + " " + name);
return null;
}
public MethodVisitor visitMethod(int access, String name,
String desc, String signature, String[] exceptions) {
System.out.println(" " + name + desc);
return null;
}
public void visitEnd() {
System.out.println("}");
}
}
- The second step is to combine this ClassPrinter with a ClassReader component,
so that the events produced by the ClassReader are consumed by our ClassPrinter
public class AsmTest {
@Test
public void testAsm() throws IOException {
ClassPrinter cp = new ClassPrinter();
ClassReader cr = new ClassReader("java.lang.Runnable");
cr.accept(cp, 0);
}
}
- result
java/lang/Runnable extends java/lang/Object {
run()V
}
Process finished with exit code 0
Generating classes
The only required component to generate a class is the ClassWriter component.
贡献者
binbin.hou