在Java中,null是堆上的一个现有对象吗?
我试图理解未初始化的局部变量(编译错误)和使用null初始化的变量之间的区别(可编译)。
我试图理解未初始化的局部变量(编译错误)和使用null初始化的变量之间的区别(可编译)。
请看这里:
Java常见问题解答: 不经常回答的问题: null是一个对象吗?
这个问题突出了作用域和明确赋值之间的联系。如果您在调试器中逐行执行下面的代码,您可以看到以下几个特点:
i
不在作用域内。i
在作用域内,但“当前上下文中未知变量”。i
已被赋值,并且它的值为null
。i
的值为1,在第4行后将被递增。清单:
Integer i;
i = null;
i = Integer.valueOf(1);
i++;
补充:
那么,null和未初始化之间有什么区别?
在 明确赋值 之前,局部变量的值是不可访问的;任何尝试访问该值的操作都会在编译时被拒绝。一旦明确赋值,即使是 null
,该值也可以被访问。这是 Java 中的一个关键安全特性。在某些语言中,未初始化变量 可能会引用先前进程留下的内存中的值。
补充:帧的局部变量 在初始化之前的内容是未指定的。字节码验证器 防止访问未初始化的内存的字节码,但是可能存在 异常字节码。
一个尚未被赋值的本地变量,很可能也指向 null。我不是 JVM 专家,但这似乎是合乎逻辑的选择。
因此编译器会检查你是否已经给变量赋值。除此之外没有任何区别。在运行时,尚未初始化的本地变量将被赋值为 null。
Null不是一个对象。实际上,它是一个对象的相反,这就是为什么你不能对指向null的引用进行方法调用的原因。如果你真的想知道null是什么,你可以把它看作是类似于零的东西。事实上,指向null的引用不会占用任何额外的内存,即零。它没有值,所以它是一个不引用任何对象的引用。
在Java中,你必须在使用变量之前初始化它。由于历史原因,Java不希望你假设值,因此编译器强制你给它赋一个值。其中一部分原因是C语言由于没有初始化值或强制你在使用之前初始化值而导致的错误和安全问题。Java会为基本类型和实例变量初始化一些值:0、0.0、false和null等,但对于局部变量,你必须给它一个值。这是为了你自己的保护。 :-)