通过reflection访问main方法中的局部变量

只是玩Javareflection,我想我大部分时间都在掌握它。 我从这个问题/答案中了解到,在大多数情况下,我仅限于静态变量。 如果我有一个类的实例,我可以访问非静态变量,这确实有意义,我得到了那么多。

说我有以下两个类:

public class A { private static int _staticInt; public static void main(String[] args) { B instanceOfB = new B(); } } public class B { private int _nonStaticInt; public Game() {} } 

我理解如何访问_staticInt ,这不是问题。 我的理解是我可以以相同的方式获取_nonStaticIntField (即Field f = B.class.getDeclaredField("_nonStaticInt"); )。 从其他研究(javadocs, _nonStaticInt等)我收集到我需要B的实例才能获得_nonStaticInt的值。

所以我的问题; 由于main是静态的,是否可以访问instanceOfB以访问_nonStaticInt的值? 我不认为这是可能的,但我认为在放弃这个想法之前,最好先咨询比我更了解的人。

由于main是静态的,是否可以访问instanceOfB以访问_nonStaticInt的值?

“没有。” 使用Java Reflection API 无法访问局部变量(是否在静态方法中)。 reflection仅适用于类型级别,而不适用于字节码级别2

对相关问题的陈述理解是正确的; 非静态(实例)字段的reflection访问逻辑上需要一个实例 。 也就是说,问题不在于反映B类型,问题在于获取 B实例(分配给局部变量)以反映。

要做到这一点,B实例必须以某种方式“放血” – 例如,分配给静态字段或作为参数传递给main 1中的方法/构造函数 – 以便稍后可以将其与reflection一起用作实例成员的对象被访问。

最干净的方法可能是将B实例向下传递到适当的上下文(或“DI”),也许可以使用IoC的助手……并且可能更改类型以避免完全使用reflection。


1另一种“流血”B实例的可能方法是附加调试器并检查/使用执行框架的主要方法中的局部变量 – 但这听起来像是试图用球杆拍打飞行。

2即使像BCEL / ASM这样的工具也不会在执行主方法时立即提供帮助。 相反,它将用于解构方法,添加所需的钩子/代码以“出血”或使用创建的实例,然后构造一个要执行的修改方法。

是的,你可以用同样的方式获得_nonStaticInt的值:

 B instanceOfB = new B(); Field f = B.class.getDeclaredField("_nonStaticInt"); // Because the variable is private you need this: f.setAccessible(true); Object content = f.get(instanceOfB); System.out.println(content); 

该值将为0,这是int的默认值。