Java 语言自动初始化对象字段的具体原因是啥?

Posted

技术标签:

【中文标题】Java 语言自动初始化对象字段的具体原因是啥?【英文标题】:For what specific reason does the Java language initialize the fields of objects automatically?Java 语言自动初始化对象字段的具体原因是什么? 【发布时间】:2011-08-08 22:53:37 【问题描述】:

“与程序员负责初始化的方法的局部变量相比,Java 语言自动初始化对象的字段。鉴于您对过程内和过程间数据流分析的了解,解释为什么语言设计者可能有做出了这些设计选择。”

对我来说很明显它是为了防止错误。但是,那个错误究竟是什么? 是不是把某个给定方法可能的控制流浓缩?

有人可以详细介绍一下吗?非常感谢您的帮助。

【问题讨论】:

那么你想让我们为你回答你的作业问题吗? 哈哈,是的。对我感到羞耻?对不起,如果我只是故意滥用这个网站。 幸好这个问题很有趣,所以没人关心=P @Claudiu 感谢您支持我,哈哈哈。这个网站让人上瘾。我一定会做出贡献以换取帮助。 【参考方案1】:

执行过程内数据流真的很容易,因此检查字段是否已初始化并在没有初始化时发出警告非常容易(可以编写一个简单的可判定算法,例如确保一个字段的所有分支if 初始化一个变量,如果一个分支没有,则失败,即使该分支不可达)。

做跨过程的数据流真的很难,所以很难检查一个对象的字段是否曾经在代码中任何地方被初始化(你迅速进入任何合理近似的不确定领域)。

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

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于Java 语言自动初始化对象字段的具体原因是啥?的主要内容,如果未能解决你的问题,请参考以下文章

selenium学习初体验-C#/java/Python

系统运维系列 之java.lang.NullPointerException出现原因研究和解决方案分析

系统运维系列 之java.lang.NullPointerException出现原因研究和解决方案分析

python中self是啥意思?

Java课后动手动脑 类与对象

java语言Class类的作用是啥以及怎么使用?