Java: список полей, используемых в методе

В Java, как я могу получить поля, которые используются в методе?

По сути, это те же вопросы, что и в . НЕТ. Я не хочу перечислять поля из класса, а перечислять поля, которые используются в данном методе класса.

Пример:

public class A {
 int a;
 int b;

public int bob(){
 return a-b;
}

Я хочу получить такие поля:

Fields[] fields = FieldReader.(A.class.getMethod("bob"));

Так что fields[0]=A.a и fields[1]=A.b

Я не нашел решения с использованием стандартного Reflection. Считаете ли вы, что библиотека для манипулирования байт-кодом, такая как ASM, подходит?


person Julien    schedule 25.03.2016    source источник
comment
Не могли бы вы немного объяснить, почему вы хотите это сделать? Вероятно, будет более простой способ, если вы сможете объяснить контекст.   -  person sprinter    schedule 25.03.2016
comment
Это для исследовательских целей, мне нужно перечислить поля, используемые в компараторе.   -  person Julien    schedule 25.03.2016
comment
Вы можете использовать asm.ow2.org/asm50/javadoc /user/org/objectweb/asm/, более конкретный visitFieldInst метод. Посмотрите руководство по ASM, это хорошая отправная точка.   -  person Grzesuav    schedule 27.03.2016


Ответы (2)


Вот пример с javassist (вам нужно добавить его как зависимость, в зависимости от вашей зависимости предпочтения менеджера).

В этом коде перечислены поля, к которым осуществляется доступ в методе public void doSomething();.

package bcm;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import javassist.bytecode.InstructionPrinter;

public class Person {

    String name;
    String surname;
    int age;

    boolean candrink = false;

    public Person(String name, String surname, int age) {
        super();
        this.name = name;
        this.surname = surname;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void doSomething() {
        if (this.age > 18) {
            candrink = true;
        }
    }

    public static void main(String[] args) throws IOException,
            CannotCompileException {
        ClassPool pool = ClassPool.getDefault();
        try {
            CtClass cc = pool.get("bcm.Person");
            CtMethod m = cc.getDeclaredMethod("doSomething", null);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PrintStream ps = new PrintStream(baos);
            InstructionPrinter i = new InstructionPrinter(ps);
            i.print(m);
            String content = baos.toString();

            for (String line : content.split("\\r?\\n")) {
                if (line.contains("getfield")) {
                    System.out.println(line.replaceAll("getfield ", ""));
                }
            }

        } catch (NotFoundException e) {
            e.printStackTrace();
        }
    }

}

ХТН

person Fafhrd    schedule 25.03.2016

Как только вы загрузите classnode, это станет невероятно просто.

// Assuming you have loaded classNode
for (MethodNode method : classNode.methods){
    for (AbstractInsnNode ain : method.instructions.toArray()) {
        if (ain.getType() == AbstractInsnNode.FIELD_INSN) {
            FieldInsnNode fin = (FieldInsnNode) ain;
            //fin.name = Field name
            //fin.owner = ClassNode's name
        }
    }
}

Кроме того, ASM намного быстрее, чем такие библиотеки, как Javassist.

person Display Name    schedule 29.03.2016
comment
Поскольку производительность вызывает беспокойство, я мог бы переключиться на это решение. Я проведу несколько тестов, чтобы сравнить оба подхода. - person Julien; 29.03.2016