为什么在Java中变量需要初始化默认值是必要的?

7
在一篇关于Java中对象初始化的文章中,有如下一段话:
在一个对象的生命开始时,Java虚拟机(JVM)在堆上分配足够的内存以容纳对象的实例变量。然而,当该内存首次分配时,它所包含的数据是不可预测的。如果直接使用该内存,则对象的行为也将是不可预测的。为了防止这种情况发生,Java确保在任何代码使用之前,内存至少被初始化为可预测的默认值。
请问这里的“不可预测的数据”和“不可预测的行为”是什么意思?谢谢。
4个回答

6
请问什么是“不可预测的数据”和“不可预测的行为”?
如果你使用C/C++编程,你会发现未初始化的变量会携带一些垃圾值,这些值存在于分配给该变量的内存位置中,并根据变量的数据类型进行解释。编译器不会对这些变量发出警告,如果开发人员忘记正确地初始化它们,那么这些垃圾值将被使用,导致程序的行为出现意外的结果。
在Java中,JVM根据变量的数据类型将所有成员变量初始化为默认值,并在编译期间报告未初始化的局部变量,以避免出现意外的行为并使开发人员始终使用初始化的变量。

4
这种不可预测性可以在C或C++中体验到,因为语言不会自动初始化变量。以下是来自维基百科的一个例子:
void count( void )
{
    int k, i;
    for (i = 0; i < 10; i++)
    {
        k = k + 1;
    }
    printf("%d", k);
}

http://en.wikipedia.org/wiki/Uninitialized_variable

我们不知道 k 的值,因为我们不知道它最初的值是什么。初始值是已分配的内存块中所包含的任何内容:0x0A4C1330、0x00000000 或 0x00FF3333 等。因此,不可预测的数据会导致(各种)不可预测的行为。

4

因为如果您不初始化变量,JVM将无法理解要分配什么值,并且它将采用任何值,这将导致数据不可预测。

编译器从不为未初始化的局部变量分配默认值。

来自维基百科:

Java没有未初始化的变量。没有显式初始化程序的类和对象的字段以及数组的元素会自动使用其类型的默认值进行初始化(布尔类型为false,所有数字类型为0,所有引用类型为null)。在Java中,局部变量必须在访问之前被明确定义,否则就是编译错误。


4
在C语言和其他编译成本机代码并在非受控环境中运行的语言中,未初始化的变量可能会持有任何随机值。这正是“不可预测”的含义。想象一下指向内存中某个未知位置的指针。如果您的程序错误地开始使用此指针,则至少会表现出不可预测的行为,如果该值用于读取,则可能会崩溃,例如,位于该随机存储单元中的值的转换无法转换为代码中写入的类型,甚至可能导致系统损坏,如果一个程序将信息写入属于另一个程序的内存区域。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接