只是玩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
的值?我不认为这是可能的,但我认为在放弃这个想法之前,最好先咨询比我自己更了解的人。
答案 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的默认值。