[ASM] 클래스 - 파싱하기
참조: http://download.fr.forge.objectweb.org/asm/asm-guide.pdf
ClassVisitor 인터페이스를 구현하여 간단하게 파싱하는 클래스 작성 가능.
public class ClassPrinter implements ClassVisitor {
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 s, String s1) {
}
public void visitOuterClass(String s, String s1, String s2) {
}
public AnnotationVisitor visitAnnotation(String s, boolean b) {
return null;
}
public void visitAttribute(Attribute attribute) {
}
public void visitInnerClass(String s, String s1, String s2, int i) {
}
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() {
}
}
이 클래스 사용하기
public void asm() throws IOException {
ClassPrinter cp = new ClassPrinter();
ClassReader cr = new ClassReader("java.lang.Runnable");
cr.accept(cp, true);
}
ClassReader 인스턴스를 만들 때 어떤 클래스를 파싱할지 지정한다.
accept를 호출하면 전달받은 ClassVisitor(여기서는 그 구현체 ClassPrinter)의 메서드를 호출하여 파싱할 클래스 정보를 파싱한다.(꼬인다 꼬여;)
java/lang/Runnable extends java/lang/Object {
run()V
결과는 위와 같음.
ClassReader 객체를 만드는 방법은 여러 가지가 있다.
ClassLaoder의 getResourceAsStream 메서드를 이용하여 가져온 InputStream으로 만들 수도 있다.
cl.getResourceAsStream(classname.replace(’.’, ’/’) + ".class");
하지만 복잡하다. 너무 저수준 API 아닌가... @_@ 이렇게까지 쓰고 싶진 않다.