我已经浏览过互联网,并没有找到满意的问题答案。在本地化的实例中,如果我有代码:
public static void main (String args[])
{
int x;
System.out.println(x);
}
...它不会编译,因为Java编译器会警告我应该初始化x。我明白了。
我的问题是,Java实际上会为整数x留出4个字节的内存吗?如果是这样,它会消灭那块内存吗?它是否将其定义为NULL(我不这么认为,因为NULL和int是不兼容的类型)?或者int x
的内存地址是否仍然保留最后存储在内存中的值,或者x
只是简单地拥有"没有值?"
我知道上面的工作在C中,而在C中,它只会打印出该内存块中的任何内容。我想知道Java如何处理这个问题。
=== EDIT ===
好的,好的。出于某种原因,我对编程的基本知识完全退出了我的想法,因为当程序无法编译时,内存分配的问题是无关紧要的,正如发布答案的两位成员所指出的那样。 (提示facepalm)
那么如果我有代码呢?
public static void main (String args[])
{
int x;
}
那么整数x
如何在内存中解析?
答案 0 :(得分:4)
这不是警告;这是一个编译器错误。该代码将无法编译,因此不会生成字节码。是否存在内存的问题是无关紧要的,因为没有程序可以运行。
但是,如果x
变量不是本地,那么Java将分配默认值0
。
程序中的每个变量在使用其值之前必须具有值:
每个类变量,实例变量或数组组件在创建时都使用默认值进行初始化(§15.9,§15.10.2):
对于type byte,默认值为零,即(byte)0的值。
对于type short,默认值为零,即(short)0的值。
对于int类型,默认值为零,即0。
对于long类型,默认值为零,即0L。
对于float类型,默认值为正零,即0.0f。
对于double类型,默认值为正零,即0.0d。
对于char类型,默认值为空字符,即'\ u0000'。
对于类型boolean,默认值为false。
对于所有引用类型(§4.3),默认值为null。
每个方法参数(第8.4.1节)都被初始化为方法调用者(第15.12节)提供的相应参数值。
每个构造函数参数(第8.8.1节)初始化为由类实例创建表达式(第15.9节)或显式构造函数调用(第8.8.7节)提供的相应参数值。
异常参数(§14.20)初始化为表示异常的抛出对象(§11.3,§14.18)。
局部变量(§14.4,§14.14)必须在使用之前通过初始化(§14.4)或赋值(§15.26)显式赋予值,其方式可以使用明确赋值的规则(§16(确定赋值))。
答案 1 :(得分:2)
鉴于您的问题是:
您寻求的答案位于JLS 4.12.3.8:
局部变量声明语句可能包含初始化变量的表达式。但是,初始化具有初始化表达式的局部变量,直到执行声明它的局部变量声明语句为止。 (明确赋值的规则(§16(Definite Assignment))防止局部变量的值在被初始化或以其他方式赋值之前被使用。)当执行块时局部变量实际上不再存在或者声明已完成。
所以答案是:
在分配之前,局部变量没有任何反应。但是,在分配之前不可能使用该值,因此您永远不能使用未初始化的值。在初始化时,必须使用某种存储位置(显然)。但是,JLS没有任何内容要求JVM分配内存。
是否分配内存将在运行时根据执行上下文确定,是否需要将值推送到堆栈帧以进行方法调用,是否有未使用的CPU寄存器等等。一个朴素的JVM实现可能只是总是分配内存,但这会很慢,因此我希望大多数真实世界的JVM都能尝试更优化的东西。