Как получить доступ к методам внутренних классов, используя ASM? - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь распечатать инструкции всех методов в файле .class.Код ниже выводит инструкции только для метода внешнего класса (main).

Как я могу получить доступ к методам внутренних классов?Я прочитал, что я могу загрузить внутренний класс, как я делаю для внешнего класса.Как я могу это сделать?

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);

Эта часть кода показывает только основную информацию о внутренних классах, например, имя внутренних классов, имя внешнего класса и флаги доступа.

final List<InnerClassNode> classes = classNode.innerClasses;
        for(InnerClassNode c: classes){
             System.out.println(c.innerName);
        } 

1 Ответ

0 голосов
/ 22 января 2019

Вложенные классы не были частью оригинальной Java.Они были добавлены только в Java 1.1, и поэтому они должны были быть адаптированы к существующему формату файла классов.Поэтому на уровне байт-кода вложенные классы - это просто обычные классы в отдельных файлах классов.Единственное, что их отличает, - это пара атрибутов метаданных, которые содержат информацию о вложенных классах исходного уровня для целей отражения и компиляции.

Таким образом, способ доступа к вложенному классу состоит в том, чтобы загрузить его и обработать как любой другой класс.Вы уже выяснили, как получить имена вложенных классов, теперь вам просто нужно создать новый ClassFileReader и рекурсивно загрузить каждый из них.

...