Java:列出方法中使用的字段

标签 java reflection java-bytecode-asm bytecode-manipulation

在 Java 中,如何获取方法中使用的字段?

基本上,这是与 this one in .NET 相同的问题.我不想列出类中的字段,而是列出类的给定方法中使用的字段。

例子:

public class A {
 int a;
 int b;

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

我想得到这样的字段:

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

因此 fields[0]=A.afields[1]=A.b

我没有找到任何使用标准反射的解决方案。你认为像ASM 这样的字节码操作库吗?是一条路要走吗?

最佳答案

这是一个 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();
        }
    }

}

HTH

关于Java:列出方法中使用的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36217102/

相关文章:

Java异常抛出内省(introspection)

java - JEdi​​torPane 无法接受 Google 搜索查询,为什么?

java - 如何在航类从 xml 创建类和对象?

java - 如何抑制 sun.reflect.Reflection 的专有 API 警告?

java - 是否可以使用 ByteBuddy 更改注释的值?

java - 在 ASM 字节码中打印一个方法

java - 多线程的新手 - 多线程的最具成本效益的方法?

javax.mail.AuthenticationFailedException : [AUTH] Web login required

java - 如何通过反射luaj传递类 - java

jvm - 如何调试 Java 代理