为什么必须始终在Java中初始化局部变量(包括基元)?

为什么必须始终在Java中初始化局部变量(包括基元)? 为什么相同的实例变量不适用?

8个解决方案

66 votes

基本上,要求在读取变量之前为其分配值是一件好事。 这意味着您不会意外阅读您不想要的内容。 是的,变量可以具有默认值-但如果编译器可以证明您正在尝试读取尚未分配的内容,那么编译器是否能够捕获错误不是更好吗? 如果要为局部变量提供默认值,则始终可以显式分配它。

现在,对于局部变量来说已经可以了-但是对于实例变量和静态变量来说,编译器无法知道方法的调用顺序。 是否会在“获取器”之前调用属性“设定者”? 它无法知道,因此也无法提醒您危险。 这就是为什么将默认值用于实例/静态变量的原因-至少,您将获得一个已知值(0,false,null等),而不仅仅是“当时内存中发生的任何事情”。 (这还消除了读取尚未明确擦除的敏感数据的潜在安全问题。)

最近C#对此有一个疑问...-也请阅读答案,因为这基本上是同一回事。 您可能还会发现Eric Lippert最近的博客文章有趣。 尽管它的推力有所不同,但至少在同一区域附近。

Jon Skeet answered 2020-01-20T19:59:15Z
8 votes

好吧,在局部变量的情况下,因为声明(在方法中)和引用之间的程序流是顺序的,所以很清楚“之前”的含义。 如果在方法之外声明了字段,则编译器永远不会知道何时将使用哪个代码,因此它不会生成错误,因为其他一些方法可能会在使用该字段之前对其进行初始化。

quosoo answered 2020-01-20T19:59:35Z
8 votes

在Java中,如果类和实例变量没有手动初始化,它们将采用默认值(null,0,false)。 但是,局部变量没有默认值。 除非为局部变量分配了值,否则编译器将拒绝编译读取该变量的代码。 恕我直言,这得出的结论是,在声明局部变量时使用一些默认值(例如null,可能会在以后导致NullPointerException)初始化它实际上是一件坏事。 考虑以下示例:

Object o;
if ()
o = ;
else
o = ;
System.out.println(o);

完全不需要使用null初始化o,因为Java编译器会在编译时检查,在读取变量之前,任何代码路径都会初始化o(使用null或某些非null值)。 这意味着,如果您要注释掉上面代码片段中变量o的两个初始化中的任何一个,则编译器将拒绝编译System.out.println(o);行。

这适用于Java,也许仅适用于Java。 我不知道像C#这样的语言。 但是,在较旧的C语言(可能还有C ++)中,仍然建议始终在声明变量AFAIK时初始化它们。 这种“老式”编程语言可能是导致始终初始化变量的建议出现在有关Java之类的现代语言的书和讨论中的原因,在Java和Java中,编译器会跟踪变量是否已初始化。

Sven answered 2020-01-20T20:00:06Z
6 votes

并非完全正确。 局部变量仅在被引用时才需要初始化。 如果从未引用局部变量,则可以不对其进行初始化。 例如:

int x; // Valid
int y;
println("y=" + y); // Not valid since y's value has never been assigned
Steve Kuo answered 2020-01-20T20:00:26Z
1 votes

局部变量和基元应在使用之前进行初始化,因为您会知道期望值。 从历史上看,当创建一个新变量时,它将包含来自内存的随机值[并且无法预测该值]。 Java也需要这样做,因为它可以防止孤立变量的存在。

monksy answered 2020-01-20T20:00:47Z
1 votes

有必要初始化局部变量(仅当我们使用它们时),因为它们不会像实例变量那样获得任何默认值。

并且作为基本规则,我们应该始终在使用任何变量之前对其进行初始化。 否则可能会导致错误,例如nullPointer等

现在,为什么局部变量不获取默认值? 原因是局部变量驻留在堆栈上,并且仅在局部方法上下文中可见,这不同于实例变量驻留在堆上并在整个程序中具有作用域。

因此,当堆栈结束时,本地方法的值也将因此被销毁:1]应该明确地初始化它们(当我们使用它们时)2]不应像实例变量一样隐式地初始化它们(通过null,0或false)。

Shashank Bodkhe answered 2020-01-20T20:01:21Z
0 votes

实际上,所有变量都需要在使用它们之前进行初始化。

我想不出您想在设置变量值之前使用变量的时间(除非您将其与null进行比较)。

James Cronen answered 2020-01-20T20:01:45Z
0 votes

根据局部变量的状态定义,局部变量在函数内声明或作为参数传递给函数。 如果不初始化局部变量,则会遇到异常处理问题,因为编译器将无法理解该变量所保存的值

udoh unyime answered 2020-01-20T20:02:05Z