Java:是否有可能在没有实例化的情况下获得字段的默认值?



我有一个不能直接实例化的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();在您的代码中,它将返回字段字段的当前值。(您可能应该更改字段的名称)

因此,要获得默认值,只需在设置字段之前运行它

相关内容

  • 没有找到相关文章

最新更新