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

时间:2011-12-20 07:45:47

标签: java reflection field default

我有一个我无法直接实例化的Java类。我需要知道其中一个字段的默认值。

e.g。

Class Foo {
  private Bar field = new Bar("baz"); // can I know that field 
                                      // is set to new Bar("baz")?
}

6 个答案:

答案 0 :(得分:1)

简单地说,你不能。

但与此同时,你可以用一些非常可怕的黑客攻击。

您可以使用反射来创建对象,然后将对象的状态更改为public,以便您可以访问它,然后获取它的值。这真的很糟糕,但我认为这是可能的。我没有准备好代码,但我确信互联网上有十亿个代码样本用于使用反射来实例化对象。

答案 1 :(得分:1)

如果无法实例化它,则无法获得其中一个字段的值。

事实上,当你想到它时,这完全是荒谬的。在创建Bar对象之前,字段的值(即对特定Bar对象的对象引用)不存在。而且只有在Foo对象被实例化时才会发生。

如果将field初始化为Java常量表达式,则更有意义,但不能使用引用类型(除了String之外)。


这里唯一可能的摆动空间是可能能够间接地实例化Foo对象,或者使用反射和setAccessible来破坏Java可见性限制。但即便如此,您还是获得了已实例化的特定field对象的Foo值...而不是尚不存在的对象的(无意义)字段值。

答案 2 :(得分:1)

字段初始化的详细信息在构造函数中。如果必须,可以使用反射调用构造函数(使用setAccessible(true))如果由于某种原因无法调用它,则可以读取类的字节代码以确定每个字段将初始化为什么。 (这实际上与调用构造函数相同,但您可以完全控制)

答案 3 :(得分:0)

您可以使用@glowcoder描述的令人敬畏但可怕的黑客来实现这一目标。但是,我不推荐它,为了Java和最终维护代码的人。

我建议你使用一些方法来检查默认值。(旧的getter / setter)无论如何,我都不明白为什么你不想做实例化。有什么特别的原因吗?

答案 4 :(得分:0)

通过一些(好的,很多)工作,你可以解析自己的字节码。对于简单的类来说,不应该太难,但想象一下这样的类:

public class Foo {
    private Bar field = OtherClass.someStaticMethod();
}

然后会更难。

答案 5 :(得分:-1)

如果我理解正确,您可以创建一个方法来返回该字段的值,如下所示:

public Bar getBar() {
     return field;
}

然后每当你使用方法getBar();在您的代码中,它将返回字段,字段的当前值。 (您应该更改字段名称)

因此,在设置字段之前,只需运行默认值即可。