如何使用 ASM 访问内部 类 的方法?
How to access methods of inner classes using ASM?
我正在尝试打印出 .class
文件中所有方法的说明。下面的代码仅打印出外部 class 方法 (main
) 的指令。
如何访问 classes 的内部方法?我读到我可以像加载外部 class 一样加载内部 class。我该怎么做?
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.List;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.util.*;
public class ClassInfoReader {
public static void main(String[] args) throws Exception{
InputStream in = new FileInputStream("MyInfo.class");
ClassReader reader = new ClassReader(in);
ClassNode classNode = new ClassNode();
reader.accept(classNode,0);
@SuppressWarnings("unchecked")
final List<MethodNode> methods = classNode.methods;
for(MethodNode m: methods){
InsnList inList = m.instructions;
System.out.println(m.name);
for(int i = 0; i< inList.size(); i++){
System.out.print(insnToString(inList.get(i)));
}
}
final List<InnerClassNode> classes = classNode.innerClasses;
System.out.println(classes);
for(InnerClassNode c: classes){
System.out.println(c.innerName);
}
}
public static String insnToString(AbstractInsnNode insn){
insn.accept(mp);
StringWriter sw = new StringWriter();
printer.print(new PrintWriter(sw));
printer.getText().clear();
return sw.toString();
}
private static Printer printer = new Textifier();
private static TraceMethodVisitor mp = new TraceMethodVisitor(printer);
这部分代码只展示了内部classes的基本信息,例如内部 classes 的名称,外部 class 的名称和访问标志。
final List<InnerClassNode> classes = classNode.innerClasses;
for(InnerClassNode c: classes){
System.out.println(c.innerName);
}
嵌套的 class 不是原始 Java 的一部分。它们仅在 Java 1.1 中添加,因此必须对现有的 class 文件格式进行改造。因此,在字节码级别,嵌套的 classes 只是单独 class 文件中的普通 classes。唯一区别它们的是几个元数据属性,这些属性包含有关源级别嵌套 classes 的信息,用于反射和编译。
因此访问嵌套 class 的方法是加载它并像处理任何其他 class 一样处理它。您已经知道如何获取嵌套 class 的名称,现在您只需要创建一个新的 ClassFileReader
并递归加载它们中的每一个。
我正在尝试打印出 .class
文件中所有方法的说明。下面的代码仅打印出外部 class 方法 (main
) 的指令。
如何访问 classes 的内部方法?我读到我可以像加载外部 class 一样加载内部 class。我该怎么做?
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.util.List;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.util.*;
public class ClassInfoReader {
public static void main(String[] args) throws Exception{
InputStream in = new FileInputStream("MyInfo.class");
ClassReader reader = new ClassReader(in);
ClassNode classNode = new ClassNode();
reader.accept(classNode,0);
@SuppressWarnings("unchecked")
final List<MethodNode> methods = classNode.methods;
for(MethodNode m: methods){
InsnList inList = m.instructions;
System.out.println(m.name);
for(int i = 0; i< inList.size(); i++){
System.out.print(insnToString(inList.get(i)));
}
}
final List<InnerClassNode> classes = classNode.innerClasses;
System.out.println(classes);
for(InnerClassNode c: classes){
System.out.println(c.innerName);
}
}
public static String insnToString(AbstractInsnNode insn){
insn.accept(mp);
StringWriter sw = new StringWriter();
printer.print(new PrintWriter(sw));
printer.getText().clear();
return sw.toString();
}
private static Printer printer = new Textifier();
private static TraceMethodVisitor mp = new TraceMethodVisitor(printer);
这部分代码只展示了内部classes的基本信息,例如内部 classes 的名称,外部 class 的名称和访问标志。
final List<InnerClassNode> classes = classNode.innerClasses;
for(InnerClassNode c: classes){
System.out.println(c.innerName);
}
嵌套的 class 不是原始 Java 的一部分。它们仅在 Java 1.1 中添加,因此必须对现有的 class 文件格式进行改造。因此,在字节码级别,嵌套的 classes 只是单独 class 文件中的普通 classes。唯一区别它们的是几个元数据属性,这些属性包含有关源级别嵌套 classes 的信息,用于反射和编译。
因此访问嵌套 class 的方法是加载它并像处理任何其他 class 一样处理它。您已经知道如何获取嵌套 class 的名称,现在您只需要创建一个新的 ClassFileReader
并递归加载它们中的每一个。