String中的null,"",以及String s;等等的區別詳解 – JAVA編程語言程序開發技術文章

1、判斷一個引用類型數據是否null。 用==來判斷。
2、釋放內存,讓一個非null的引用類型變量指向null。這樣這個對象就不再被任何對象應用瞭。等待JVM垃圾回收機制去回收。

============================================

null和""的區別
問題一:
null和""的區別
String s=null;
string.trim()就會拋出為空的exception 
String s=""; 
string.trim()就不會拋,為什麼?
答:
NULL代表聲明瞭一個空對象,根本就不是一個字符串。 
""代表聲明瞭一個對象實例,這個對象實例的值是一個長度為0的空字符串。
 
NULL代表聲明瞭一個空對象,對空對象做任何操作都不行的,除瞭=和== 
""是一個字符串瞭,隻是這個字符串裡面沒有內容瞭
 
String s=null;隻是定義瞭一個句柄,也就是說你有瞭個引用,但是這個引用未指鄉任何內存空間 
String s="";這個引用已經指向瞭一塊是空字符串的內存空間,是一個實際的東東瞭,所以你可以對它操作,而不用擔心什麼瞭
 
你說數字0和沒有是不是一種概念啊??道理一樣的
 
而且,null可以賦值給任何對象.""就不行瞭.
 
這裡""和NULL絕對是兩個概念 
""代表一個字符串存在,它的值就是“” 
NULL代表字符串根本沒有實際的值,你並不知道它是什麼。。。
 
哦,我明白瞭,意思就是String   string   =   null   跟String   string;是一回事兒
 
null是空對象     ""是空字符串
String s=null;//null是未分配堆內存空間 
String   a;//分配瞭一個內存空間,沒存入任何對象 
String   a="";//分配瞭一個內存空間,存瞭一個字符串對象
 
 
 
問題二:
String s;和String s=null;和String s="a";有什麼區別? 
針對這三種情況,使用out.println(s);的時候,第一個會出現異常,第二個會輸出null.第三個則會輸出a. 
這是為什麼呢?這三句聲明語句,各自作瞭什麼呢?
 
答:
第一個隻是定義瞭一個String類型變量s,並沒有給它賦初值,在Java中,默認在使用一個變量的時候必須賦予它初值(降低風險)。
第二個和第三個都定義瞭String類型變量s,並賦予它初值,隻不過第二個賦予的值為null(空)罷瞭
 
主要要理解的是String s; s為一個引用~~它不是對象 
第一個是沒有初始化的引用; 
第二個為空引用;
第三個是在字符串池裡寫入一個字符'a',然後用s指向它。
另外, 
String s="a"和String s=new String("a");是有本質上的區別的 
前者是在字符串池裡寫入一個字符'a',然後用s指向它;
後者是在堆上創建一個內容為"a"的字符串對象。
String   str="aaa";                    //於棧上分配內存
String   str=new   String("aaa");      //於堆上分配內存
 
String s; 系統會自動賦值null
 
String s;隻是給s分配一個內存空間 
String s=null;是分配的空間中存儲的值為空值 
String s="a";這句就不用我多說瞭分配的空間的值為字符a
 
 
 
問題三:
聲明瞭一個string a;變量  
在以後的判斷中,a==""和a==null有何不同? 
 
答:
如果沒有給a賦過值,a==""會導致異常。   
在實際處理時,往往認為""和null代表相同的含義,即都代表無值。 
此時建議用如下語法: 
if(a==null   ||   a=="") 


如果a為null,就不會執行後面的判斷,直接返回true。 
 
null是用來判斷引用類型是否分配瞭存儲空間 
""是針對字符串的; 
string類型實際上是字符串指針,也即是一個引用類型 
所以如果沒有給a賦過值,a==""會導致異常 
所以if(a==null   ||   a==""){}這種寫法也是正確的
 
 
問題四:
String abc=null;String abc="";String abc;三種寫法有什麼區別?
 
答:
1:創建一個空字符串對象, 
2:創建一個字符串為空的字符串對象。 
3:聲明一個字符串對象,但並沒有分配內存,而1,2已經分配瞭內存 
對於最後一種表示,你不能if(abc==null),或者int   length   =   abc.length();編譯的時候會提示可能沒有初始化.
 
 
String   abc=null; 
String   abc=""; 
一般推薦使用第二種 
第一種abc指向null,很多時候要判斷字符串是否為空時,容易漏掉這種情況,在調用String的相關方法的時候就會出錯www.aiwalls.com 
第二種則相對簡單,String的方法都可以用,判斷的時候也不會出錯
 
1) String   abc=null; 
2) String   abc;  
3)String   a=""; 
4) String   b=""; 
5) String   c=new String(""); 
6) String   d=new String("");
//1)等於2),和C語言不同,JAVA為安全原因不允許一個懸掛引用,沒有賦值的引用地址一律自動賦值為NULL,以防止訪問到任意內存 
//3)和4)中,變量a和b將會指向同一內存地址(""的地址) 
//5)和6)中,變量c和d不會指向同一地址,而是兩個""內容的地址,並且和a,b不同,實際上,3)和4)相當於new String("").intern(). 
//String類維護著一個字符串池,對於像3)和4)這樣的賦值方法,String會在這個池中查找字符串是否已經在池中,如果在,就直接指向該地址,
 
如果不在,生成一個實例放入池中再指向那個地址,可見對於同樣內容的字符串多次引用時3)4)的方法要比5)6)的方法剩內存,之所以這樣做,是
 
因為String是一個內容不可變的量,運用的是設計模式GOF.FlyWeight 
 
 
 
 
但有個關鍵的一點,沒有人說到,這就是: 
String s;在什麼情況下可以等同於String s=null;而在什麼情況下又不等同?!
考慮下面的代碼: 
//StringTest.java 
public   class   StringTest   {    
    static   String   s;     //* 
    public   static   void   main(String[]   args)   { 
        //String   s;         //** 
        System.out.println(s); 
    } 
}   
編譯並運行上面的代碼,將打印null。
可見標有*號的行是自動初始化瞭的(s被自動初始化為null)。 
而如果把標有**號的行取消註釋,代碼將不能通過編譯,這是因為這行定義的是本地變量,而本地變量是不會自動初始化的。
由此得出結論:
在成員變量的定義中,String s;等同於String s=null;
而在本地變量(方法變量)的定義中,String s;不等同於String s=null;,這時要使用s必須顯式地賦值。
這些雖然是小知識點,但在實際應用中很重要,也很容易被一些人忽視,特此提出。
還有一點要說明的是:
隻要是在方法在中定義變量都要顯示賦初值,main()方法也不例外,而在方法之外編譯器回自動賦初值。 

摘自 kofandlizi的專欄 

發佈留言