在主方法中声明String str;
栈内存中会开辟一块空间用来保存引用strString str = null;
这句话同上,只会在内存的栈中开辟一块空间保存String引用str,并没有在堆中建立任何对象,或者令引用str指向堆中的某个位置可是,为什么再后面的代码中,如果需要使用str的时候,第一句话会报错(未被初始化),第二句话却不会报错呢?
难道说,令str=null;意味着str会指向堆内存中的某个位置?

解决方案 »

  1.   

    null 空对象吧,也许正如你说的令str=null;意味着str会指向堆内存中的某个位置。
      

  2.   

    一个是在堆取分配了个地址,但是没有分配内存,而没有复制null的就连地址也没有分配!
    (一个初始化了,一个没有!)
      

  3.   

    初始化一个局域变量为null,是为了在非法使用此变量时报空指针异常,容易找到错误发生的地方,只是一个习惯,不是必须
      

  4.   

    在堆内存中为str分配了未指向任何有效内存的null值

    String str;
    中 str是个空引用
      

  5.   

    String str; // 这是声明一个String变量,由系统分配堆中的一个地址
    String str = null; // 这种方式,是声明一个String变量,但是你暂时不想给它分配对象,那么就用一个null来完成初始化,null是对空对象的一个标识在第一种情况下,java不允许对没有初始化的对象进行操作,所以这个时候会报一个编译错误,说让你初始化这个对象。
      

  6.   

    String str; color=#FF0000]系统不会分配堆中的一个地址[/color]
      

  7.   

    用c++跟你解释一下在main方法中声明的变量都是局部变量
    String a;相当于String *a;//a里存的是地址,地址并没有初始化为0,还是原先那块内存的值(相当于指针指向了一块地址,而这块地址可能并不是你程序使用的地址),如果没有初始化就使用,后果是可怕的,所以java禁止使用未初始化局部变量String a = null相当于String *a = 0;将指针不指向任何元素
      

  8.   

    String s ="a";与String s = new String("a");
    有本质的区别:前者是在字符串池里写入一个字符‘a’,然后用s指向它。
      后者是在堆上创建一个内容为“a”的字符串对象。
    String s ="a"; //于栈上分配内存
    String s = new String("a"); //于堆上分配内存
    String a = null;赋予的值为null,是分配的空间中存储的值为null值。(是为a引用在栈中(字符串池里)分配的值为null值)
    -------------------------------------------------------------------------------------
    Object o; 这种写法只是分配一个引用而已。
    Object o = null; 这么写则是给引用指向了一个空对象。具体差别如下:
    class Test {  public static void main(String[] args) {
      Object o1;
      o1.toString(); /*这里编译不能通过,编译器只认定o1是个引用,没指向任何对象,所以不能调用方法。*/
      Object o2 = null;
      o2.toString(); /*这里编译可以过,但是有空指针异常,编译器认定o2是一个对象,虽然是一个空对象。*/
      }
    }
    一个是给一个不存在的人取名字,一个是给死人取名字。你叫不存在的人吃饭这个是谬论,叫死人吃饭则是忽悠。  
    null对象是一个特殊的对象,他可以是任何类型。他只是作为一个标记而已,只是为了标记不存在而存在的。也没必要去追究他在内存是什么样。null就是一个标记而已。容器可以接受一个空对象,但是一个空引用则是不接受的
      

  9.   

    楼上的答案已经很详细了,lz还可以在看一些java虚拟机分配的一写知识
      

  10.   

    在main方法中声明的变量都是局部变量
    String a;相当于String *a;//a里存的是地址,地址并没有初始化为0,还是原先那块内存的值(相当于指针指向了一块地址,而这块地址可能并不是你程序使用的地址),如果没有初始化就使用,后果是可怕的,所以java禁止使用未初始化局部变量String a = null相当于String *a = 0;将指针不指向任何元素
      

  11.   

    多谢楼上各位前辈的热心解答,还是JavaSE版人气高啊可惜老紫竹,ZangXT大侠,火龙果,猴子等前辈不见了
      

  12.   

    打个比方
    String str;就像你准备生产一个盒子,在盒子生产出来之前你给它了名字叫str,但盒子到底是什么却没有实体
    而String str=null;就像你已经生产了盒子,给这个盒子起名叫str
    换做内存就是:String str;就是给出了堆栈空间的名字,却没有给出堆栈的实际空间
    而String str=null,就是给出了堆栈的空间名字,并且给出了堆栈的空间,虽然这个空间什么都没有                                                   ----初学者的一点浅薄理解,有不对的地方请大侠指正
      

  13.   

    多谢各位的热心分享,试着总结:1) String str;
    栈内存开辟一块空间,存储str引用2) String str = null;
    栈内存开辟一块空间,储存str引用,
    栈内存中(或者堆内存中?)开辟一块空间,
    str指向那块空的内存的地址3)String str = new String("String");
    栈内存开辟一块空间,储存str引用,
    堆内存中开辟一块空间,储存新建的String对象“String”,
    str指向堆内存中新String对象的地址
      

  14.   

    2)是在堆内存中
    3)String str = new String("hello"); 先在内存的常量池中查询是否存在“hello”,如存在,则将该块空间复制一份到内存的堆区间上,并将str指向该块区域,如不存在,则先在常量池中创建 一个“hello”,然后将其复制到堆,再令str指向它。就是说无论如何都必然会创建一个新的Hello字符串对象,不管你字符串池有没有结贴 啦啦啦~~~  其实我也不懂 抄来的 呼呼
      

  15.   

    敢问楼上的大侠,如果是:
    String str = null;
    str = "String";这种情况,第一句话还是在堆内存中开辟空间吗?
      

  16.   


    应该是开辟的,null 和  什么都不写是有区别的
    你可以理解:一个平台,String str;表示平台上什么都没有,及没有开辟空间,String str=null;表示平台上有一个空箱子,虽然箱子里什么都没有,但仍然是开辟了空间的
      

  17.   

    恩俺的意思是,
    String str = null;
    str = "String";
    最后的"String"对象是建立在栈里的,而不是堆里的,这样一来,第一句话,仍然还是在堆中开辟空间么?因为最后的对象其实是在栈中,如果一开始声明null的时候,在堆中开辟空间,岂不是有点奇怪?
      

  18.   

    我感觉看过 Thinking in Java 的人就喜欢研究这种问题!
      

  19.   

    终于再次看到久违的火龙果大侠了3年前还是3星,现在变成了5星另一个厉害人物ZangXT貌似很久没来过了
      

  20.   


    String这种可以当做基本类型类使用的特殊关键字。不太适合来研究对象。个人见解。
      

  21.   

    1. null不是一个对象,JLS 3.10.7 中提及的是The Null Literal,况且它是ASCII中值为0的一个字符
    2. null instanceof Object 是false 也证明了它不是Object
    3. null在JVM全局内存中只存在一个,因为它无需存在多个,造成不必要浪费,因此挺符合String interned的初衷。All literal strings and string-valued constant expressions are interned. 我觉得null勉强能算是literal string,因为它是基于字符的。综上,既不是Object又够格interned,所以认为null是在栈中开辟。
      

  22.   

    赋值为null的最后都会被JVM回收机制所回收,并不会去占用内存!
      

  23.   

    看看下面的字节码,LZ就明白了  Code:
       0:   aconst_null
       1:   astore_1
       2:   ldc     #19; //String String
       4:   astore_1
       5:   return  LineNumberTable:
       line 12: 0
       line 13: 2
       line 16: 5  LocalVariableTable:
       Start  Length  Slot  Name   Signature
       0      6      0    args       [Ljava/lang/String;
       2      4      1    str       Ljava/lang/String;
      

  24.   

    来个总结吧:int test(){
    String str = null;
    str = "String";
    }
    像这种String str = xxx;
    不管xxx是null还是其他字符串,str这个东西都是在栈里有块空间,可以理解为c的指针,=null的时候,里面存的是0,非null的时候存的是实际字符串的地址(堆中或者常量池中)。而String str;
    这种情况,jvm同样也为其分配了一块空间,但是不知道值是多少
    java语法要求引用之前必须初始化,所以你直接这么写,str根本不能引用,所以无所谓。
    其实jvm也完全可以不为它分配空间。这个问题,说到底,其实就是java的语法要求,必须初始化的问题。如果有C语言经验的话,可能有这样的问题,
    int i;
    int j = i; //使用了未初始化的i
    因为i没有初始化,所以i是个“随机的值”,比如i可能是5,可能是8,可能是……
    java为了避免这种问题,语法上规定,局部变量在使用之前,必须初始化!如果不初始化就报错。
      

  25.   

    不知ZangXT大侠,火龙果,老紫竹等前辈有什么高见