Java: list fields used in a method

In Java, how can I get the fields that are used in a method?

Basically, these are the same questions as this one in .NET . I do not want to list the fields from the class, but to list the fields that are used in this class method.

Example:

public class A { int a; int b; public int bob(){ return ab; } 

I want to get the following fields:

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

So fields[0]=Aa and fields[1]=Ab

I did not find a solution using standard Reflection. Do you think that a way to manipulate a bytecode library like ASM ?

+5
source share
2 answers

Here is an example with javassist (you need to add it as a dependency, depending on your dependency manager settings).

This code lists the access to the field in the public void doSomething(); method 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(); } } } 

NTN

+2
source

Once you load the class, it will become incredibly easy.

 // 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 name } } } 

Plus, ASM is much faster than libraries like Javassist.

+1
source

Source: https://habr.com/ru/post/1245760/


All Articles