【问题标题】:Accessing local variables in the main method via reflection通过反射访问main方法中的局部变量
【发布时间】:2014-06-07 06:07:15
【问题描述】:

只是在玩 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 f = B.class.getDeclaredField("_nonStaticInt");)获得_nonStaticIntField。从其他研究(javadocs、trails 等)中,我收集到我需要一个 B 的实例才能获得 _nonStaticInt 的值。

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

【问题讨论】:

标签: java reflection


【解决方案1】:

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

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

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

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

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


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

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

【讨论】:

  • @jahroy 也许吧。我正在阅读它,因为 OP 无法访问 created 实例,因此希望“访问局部变量” - 如果变量是可访问的,那么分配给此类的对象很容易获得,并且成员字段可以通过反射访问。
  • 这是最不幸的,因为我无法控制 A 或 B。没关系,我只是想变得邪恶/狡猾。感谢您简洁明了的回答。
【解决方案2】:

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

【讨论】:

  • 阅读问题——“是否可以访问instanceOfB 以访问_nonStaticInt 的值”。 OP 已经知道如何获取变量。
  • 我的错。感谢您的评论。
猜你喜欢
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 2010-12-18
相关资源
最近更新 更多