Java中的默认原始值 - 内存分配?

时间:2014-10-16 19:03:56

标签: java memory default default-value

我已经浏览过互联网,并没有找到满意的问题答案。在本地化的实例中,如果我有代码:

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如何在内存中解析?

2 个答案:

答案 0 :(得分:4)

这不是警告;这是一个编译器错误。该代码将无法编译,因此不会生成字节码。是否存在内存的问题是无关紧要的,因为没有程序可以运行。

但是,如果x变量不是本地,那么Java将分配默认值0

Section 4.12.5 of the JLS州:

  

程序中的每个变量在使用其值之前必须具有值:

     
      
  • 每个类变量,实例变量或数组组件在创建时都使用默认值进行初始化(§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)

鉴于您的问题是:

  1. [W]生病Java实际上为整数x?
  2. 留出了4个字节的内存
  3. 如果是这样,它会消灭那块记忆吗?
  4. 您寻求的答案位于JLS 4.12.3.8

      

    局部变量声明语句可能包含初始化变量的表达式。但是,初始化具有初始化表达式的局部变量,直到执行声明它的局部变量声明语句为止。 (明确赋值的规则(§16(Definite Assignment))防止局部变量的值在被初始化或以其他方式赋值之前被使用。)当执行块时局部变量实际上不再存在或者声明已完成。

    所以答案是:

    1. 也许。该值将存储在某处
    2. 是。 JLS不允许使用未初始化的值。
    3. 在分配之前,局部变量没有任何反应。但是,在分配之前不可能使用该值,因此您永远不能使用未初始化的值。在初始化时,必须使用某种存储位置(显然)。但是,JLS没有任何内容要求JVM分配内存。

      是否分配内存将在运行时根据执行上下文确定,是否需要将值推送到堆栈帧以进行方法调用,是否有未使用的CPU寄存器等等。一个朴素的JVM实现可能只是总是分配内存,但这会很慢,因此我希望大多数真实世界的JVM都能尝试更优化的东西。