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

时间:2014-06-07 06:07:16

标签: java reflection

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

说我有以下两个类:

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,这不是问题。 我的理解是,我可以以同样的方式获得Field _nonStaticInt(即Field f = B.class.getDeclaredField("_nonStaticInt");)。从其他研究(javadocs,trail等)我收集到我需要一个B的实例才能获得_nonStaticInt的值。

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

2 个答案:

答案 0 :(得分:4)

  

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

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

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

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

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


1 “爆发”B实例的另一种可能方法是附加调试器并检查/使用执行帧的主要方法中的局部变量 - 但这听起来就像试图用俱乐部拍苍蝇一样。

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

答案 1 :(得分:-1)

是的,你可以用同样的方式获得_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的默认值。