Java语言为什么会自动初始化对象的字段?

7
"Java语言会自动初始化对象的字段,与方法的局部变量不同,程序员需要负责初始化。根据您对程序内和程序间数据流分析的了解,请解释为什么语言设计者可能做出这些设计选择。"
很明显,这是为了防止错误。但是,到底是哪种错误呢? 这是否会压缩某个给定方法的可能控制流?
能否有人详细解释一下?我真的非常感谢您的帮助。

1
那么你想让我们替你回答作业问题,是吗? - Jonathan Grynspan
哈哈,是啊。我有错吗?如果我故意滥用了这个网站,对不起。 - VitaminYes
3
幸运的是,这个问题很有趣,所以没有人在意 =P - Claudiu
@Claudiu 谢谢你在这件事上支持我,哈哈哈。这个网站真是让人上瘾。我一定会为帮助做出贡献的。 - VitaminYes
2个回答

3

在函数内部进行数据流分析非常容易,因此很容易检查字段是否已经初始化,并在未初始化时发出警告(可以编写一个简单的可判定算法,例如确保if语句的所有分支都初始化了变量,如果有一个分支没有,则失败,即使该分支是无法到达的)。

在函数间进行数据流分析非常困难,因此很难检查对象的字段是否已经在代码中的任何地方被初始化过(对于任何合理的近似值,你很快就会进入不可判定的领域)。

因此,Java只做前者,在检测到未初始化的局部变量时会给出编译时错误,但不会做后者,并将对象的字段初始化为它们的默认值。


1

它并不总是被初始化的情况。可以使用反射与类sun.misc.Unsafe或ObjectInputStream结合使用,访问这些类的私有本地方法或直接通过JNI实例化对象而不调用任何构造函数。这些旨在进行对象序列化/反序列化,并期望反序列化程序填充字段。至于为什么设计者选择消除对这些方法的直接访问(即没有反射),原因在于内存中仍然留下的指针可能会用于堆栈破坏或返回到lib-c攻击。为大多数程序“自动”清除分配给这些内存的内存减少了安全风险,同时也减少了错误的机会。还要注意,尝试读取未初始化的局部变量会由于同样的原因导致编译错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接