我有一个不能直接实例化的Java类。我需要知道其中一个字段的默认值。
。
Class Foo {
private Bar field = new Bar("baz"); // can I know that field
// is set to new Bar("baz")?
}
简单来说,你不能。
但与此同时,你可以用一些非常可怕的技巧。
您可以使用反射来创建对象,然后将对象的状态更改为public,以便您可以访问它,然后获取它的值。这样做真的很糟糕,但我想这是可能的。我没有准备好代码,但我确信互联网上有十亿代码样本用于使用反射实例化对象。
如果你不能实例化它,你就不能得到其中一个字段的值。
事实上,仔细想想,这完全是无稽之谈。字段的值(即对特定Bar
对象的对象引用)在Bar
对象创建之前不存在。这只有在Foo
对象实例化时才会发生。
如果field
初始化为Java常量表达式,这将更有意义,但是您不能使用引用类型(除了String
)。
这里唯一可能的回旋余地是可能能够间接地实例化Foo
对象,或者通过使用反射和setAccessible来打破Java可见性限制。但即使这样,您正在获得您实例化的特定Foo
对象的field
值…
字段如何初始化的细节在构造函数中。如果必须的话,可以使用反射调用构造函数(使用setAccessible(true))。如果由于某种原因不能调用它,可以读取类的字节码,以确定每个字段将被初始化为什么。(这实际上与调用构造函数相同,但您可以完全控制)
您可以使用@glowcoder描述的令人敬畏但可怕的黑客来实现这一点。但是,为了Java和最终维护您的代码的人,我不推荐这样做。
我建议您使用一些方法来检查默认值。(旧的getter/setter)无论如何,我不明白为什么你不想实例化。有什么特别的原因吗?
通过一些(好的,很多)工作,您可以自己解析字节代码。对于简单的类,这应该不会太难,但是想象一个这样的类:
public class Foo {
private Bar field = OtherClass.someStaticMethod();
}
如果我理解正确的话,您可以创建一个方法来返回该字段的值,如下所示:
public Bar getBar() {
return field;
}
当你使用getBar();在您的代码中,它将返回字段字段的当前值。(您可能应该更改字段的名称)
因此,要获得默认值,只需在设置字段之前运行它