为什么必须始终在Java中初始化本地variables(包括基元)?

为什么必须始终在Java中初始化本地variables(包括基元)? 为什么在实例variables的情况下也是不适用的?

最近有一个关于C#的问题 – 也读了那里的答案,因为它基本上是一样的。 Eric Lippert最近的博客文章很有趣, 它至less在同一地区,即使它有不同的推力。

基本上,在读取variables之前先要赋一个variables值是一件好事。 这意味着你不会意外地阅读你不想要的东西。 是的,variables可以有默认值 – 但是如果能够certificate您正在尝试读取可能尚未分配的内容,那么编译器是否能够更好地捕获错误呢? 如果你想给一个局部variables一个默认值,你总是可以明确地赋值。

现在对于局部variables来说很好 – 但是对于实例和静态variables,编译器无法知道方法的调用顺序。 在“getter”之前会调用一个属性“setter”吗? 它没有办法知道,所以它没有办法提醒你的危险。 这就是为什么默认值用于实例/静态variables – 至less你会得到一个已知的值(0,false,null等),而不仅仅是“当时在内存中发生了什么”。 (这也消除了读取未被明确清除的敏感数据的潜在安全问题。)

那么,在局部variables的情况下,由于声明(在方法中)和参考之间的程序stream程是连续的,所以它明确表示“之前”是什么意思。 如果在方法之外声明的字段,编译器永远不会知道哪个代码将被使用,所以它不能产生错误,因为在使用之前可能有其他方法将初始化该字段。

在Java中,类和实例variables如果没有手动初始化,就会采用默认值(null,0,false)。 但是,局部variables不具有默认值。 除非一个局部variables被赋值,否则编译器将拒绝编译读取它的代码。 恕我直言,这导致了这样的结论:初始化一个局部variables具有一些默认值(如null,这可能会导致一个NullPointerExceptionexception),当它被声明时,实际上是一件坏事。 考虑下面的例子:

Object o; if (<some boolean condition>) o = <some value>; else o = <some other value>; System.out.println(o); 

使用null初始化o是完全不必要的,因为Java编译器在编译时检查任何代码path在读取variables之前初始化o (具有null或某个非null值)。 这意味着,编译器将拒绝编译行System.out.println(o); 如果你想在上面的代码片段中注释variableso的两个初始化。

这适用于Java,也可能仅适用于Java。 我不懂C#这样的语言。 然而,在老C(也许是C ++)中,仍然build议在声明它们时总是初始化variablesAFAIK。 这样的“老派”编程语言可能是这样的原因,总是初始化variables的build议在关于现代语言(如Java)的书籍和讨论中popup,其中编译跟踪variables是否已被初始化。

局部variables和原语应该在使用之前初始化,因为你会知道从值中可以得到什么。 从历史上看,当创build一个新的variables时,它将包含来自内存的随机值[并且无法预测值]。 Java也要求这样做,因为它可以防止孤立variables的存在。

不完全正确。 局部variables只需要被引用即可初始化。 如果没有引用,局部variables可以保持未初始化。 例如:

 int x; // Valid int y; println("y=" + y); // Not valid since y's value has never been assigned 

在实践中,所有variables在使用前都需要初始化。

我想不出你想在设置它的值之前使用一个variables(除非你将它与空值进行比较)。