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 语言自动初始化对象字段的具体原因是啥?的主要内容,如果未能解决你的问题,请参考以下文章
系统运维系列 之java.lang.NullPointerException出现原因研究和解决方案分析