在一篇关于如何在 Java 中初始化对象的文章中,有一段如下所示:
在对象生命的开始,Java 虚拟机 (JVM) 在堆上分配足够的内存来容纳对象的实例变量。但是,当首次分配该内存时,它包含的数据是不可预测的。如果内存按原样使用,对象的行为也将是不可预测的。为了防止出现这种情况,Java 确保在任何代码使用内存之前,至少将内存初始化为可预测的默认值。
谁能解释一下这里unpredictable data
的意思unpredictable behavior
。提前致谢
在一篇关于如何在 Java 中初始化对象的文章中,有一段如下所示:
在对象生命的开始,Java 虚拟机 (JVM) 在堆上分配足够的内存来容纳对象的实例变量。但是,当首次分配该内存时,它包含的数据是不可预测的。如果内存按原样使用,对象的行为也将是不可预测的。为了防止出现这种情况,Java 确保在任何代码使用内存之前,至少将内存初始化为可预测的默认值。
谁能解释一下这里unpredictable data
的意思unpredictable behavior
。提前致谢
任何人都可以在这里解释不可预测的数据和不可预测的行为是什么意思。
如果您使用 C/C++ 编程,您会注意到未初始化的变量带有一些垃圾值,存在于分配给它的内存位置中,根据变量的数据类型进行解释。编译器不会抱怨这些变量,如果开发人员忘记正确初始化它们,垃圾值就会被使用,从而导致程序出现意外行为。
在 Java 中,JVM 会根据变量的数据类型将所有成员变量初始化为默认值,并在编译过程中抱怨局部变量未初始化,以避免此类意外行为,并使开发人员始终使用已初始化的变量。
因为如果您不初始化变量,那么 JVM 将无法理解要分配的内容,并且它将采用任何会导致不可预测数据的值。
编译器永远不会为未初始化的局部变量分配默认值。
来自维基百科:
Java 没有未初始化的变量。没有显式初始化程序的类和对象的字段以及数组元素会自动使用其类型的默认值进行初始化(布尔值为 false,所有数值类型为 0,所有引用类型为 null)。Java 中的局部变量必须是在访问它们之前肯定分配给它们,否则是编译错误。
这种不可预测性可以在 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 等。因此,不可预测的数据会产生(各种)不可预测的行为。
在 C 和其他编译为本机代码并在非受控环境中运行的语言中,未初始化的变量可以保存任何随机值。这正是术语“不可预测”的含义。想想指向内存中某个未知位置的指针。如果你的程序错误地开始使用这个指针,如果这个值被用于读取,它至少会出现不可预测的行为,它可能会崩溃,因为例如位于该随机存储单元的值的转换不能转换为用代码编写的类型,甚至会导致系统损坏如果一个程序将信息写入属于另一个程序的内存区域。