为什么局部变量,包括原语,总是要在Java中初始化?

py49o6xq  于 2023-03-11  发布在  Java
关注(0)|答案(9)|浏览(121)

为什么局部变量,包括原语,总是必须在Java中初始化?为什么同样的方法不适用于示例变量的情况?

rfbsl7qr

rfbsl7qr1#

基本上,要求变量在你读它之前被赋值是一件好事。这意味着你不会意外地读到你不想读的东西。是的,变量可以有默认值--但是对于编译器来说,能够捕捉到你的bug不是更好吗?如果它能证明你正在读取一些可能还没有赋值的东西,如果你想给予一个局部变量一个默认值,你总是可以显式地赋值。
这对于局部变量来说很好,但是对于示例和静态变量来说,编译器无法知道方法被调用的顺序。属性“setter”会在“getter”之前被调用吗?编译器无法知道。所以它没有办法提醒你注意危险,这就是为什么默认值 * 被 * 用于示例/静态变量--至少这样你会得到一个已知的值(0、false、null等)而不是“当时内存中发生的任何事情”(它还消除了阅读未显式擦除的敏感数据的潜在安全问题)。
最近有一个关于C#的问题...... --也读一下那里的答案,因为基本上是一样的。它至少在相同的区域,尽管它的推力有些不同。

rdrgkggo

rdrgkggo2#

在Java中,类和示例变量采用缺省值(null,0,false)。然而,局部变量没有默认值。除非局部变量已经被赋值,否则编译器将拒绝编译读取它的代码。恕我直言,这会导致一个结论,即用某个默认值初始化局部变量(比如null,这可能会在以后导致NullPointerException)实际上是一件坏事。

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

使用null初始化o是完全不必要的,因为Java编译器在编译时检查任何代码路径是否初始化o(空值或非空值)。这意味着,语句中注解掉变量o的两个初始化中的任何一个,编译器将拒绝编译行System.out.println(o);上面的代码片段。
这适用于Java,也许只适用于Java。我不知道像C#这样的语言。(可能还有C++)然而,仍然建议在声明变量时总是初始化变量,AFAIK。这样的“老派”编程语言可能是原因,总是初始化变量的建议突然出现在关于Java等现代语言的书籍和讨论中,其中编译器跟踪变量是否已被初始化。

whlutmcx

whlutmcx3#

不完全正确。局部变量只有在被引用时才需要初始化。如果从未被引用,则可以不初始化局部变量。例如:

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

8wtpewkr4#

好吧,对于局部变量来说,"before“的意思很清楚,因为声明(在方法中)和引用之间的程序流是顺序的。对于在方法之外声明的字段,编译器永远不知道什么时候会使用哪个代码,所以它不会生成错误,因为可能有其他方法会在使用字段之前初始化它。

vxf3dgd4

vxf3dgd45#

局部变量和基元应该在使用前初始化,因为你会知道从值中期待什么。历史上,当一个新的变量被创建时,它会包含来自内存的随机值[并且人们无法预测该值]。Java也要求这样做,因为它防止了孤立变量的存在。

eni9jsuy

eni9jsuy6#

实际上,所有变量在使用之前都需要初始化。
我想不出在设置变量值之前需要使用变量的情况(除非将其与null进行比较)。

vxqlmq5t

vxqlmq5t7#

初始化局部变量是必要的(只有当我们使用它们时),因为它们不像示例变量那样获得任何默认值。
作为一个基本规则,我们应该在使用任何变量之前初始化它,否则可能会导致nullPointer等错误
那么,为什么局部变量没有默认值呢?原因是局部变量驻留在堆栈上,并且只在局部方法上下文中可见,不像示例变量驻留在堆上,并且作用域贯穿整个程序。
所以当堆栈结束时,本地方法的值也会被销毁,因此:1]它们应该显式初始化(当我们使用它们时)2]它们不应该像示例变量那样隐式初始化(通过null、0或false

laximzn5

laximzn58#

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

xv8emn3q

xv8emn3q9#

关于栈,再多说几句话。Java是一种安全的语言,不像C++,因此在编译器级别上,方法变量必须在第一次使用之前初始化,因为如果不这样做,那么以前的值可能会被读取,这是不安全的。第二个原因是速度。栈不清理内存--这就是为什么它工作得快。也就是说,他只需要移动光标。

相关问题