null和""的區別

首先:
我們必須明白如下基本要領(對於很多人來說這是小菜一碟):bookId=""與bookId=null是不等價的!!當然與bookId=" "更不等價了!
驗證如下,程序aaa.java:
public class aaa{
public static void main(String args[])
{
String s="";
String t=null;
if(s==t) System.out.println("hello啊不如,飯已ok了!");
else     System.out.println("hello啊不如,飯沒做好呢!");
}
}
結果爲:
C:\>javac aaa.java
C:\>java aaa
hello啊不如,飯沒做好呢!

結論:String s="";與String s=null;不等價!!

第二:
public class aaa{
public static void main(String args[])
{
String s="";

if(s==null) System.out.println("不如:s==null");
if(s=="") System.out.println("不如:s==''");
if(s.length()==0) System.out.println("不如:s。length==0");
if(s.equals("null")) System.out.println("不如:s。equals null");

}
}
結果爲:
C:\>javac aaa.java
C:\>java aaa
不如:s==''
不如:s。length==0

結論:String s="";可以和null比較,可以和""比較,可以使用String類的所有方法。


第三:


public class aaa{
public static void main(String args[])
{
String s=null;

if(s==null) System.out.println("不如:s==null");
if(s.length()==0) System.out.println("不如:s。length==0");
if(s.equals("null")) System.out.println("不如:s。equals null");

}
結果爲:
C:\>javac aaa.java
C:\>java aaa
不如:s==null
Exception in thread "main" java.lang.NullPointerException
        at bbb.main(aaa.java:7)

結論:String s=null;可以和不可以使用String類的方法。

我們把
if(s.length()==0) System.out.println("不如:s。length==0");

if(s.equals("null")) System.out.println("不如:s。equals null");
交換位置後結果依然沒有同上。
Exception in thread "main" java.lang.NullPointerException
        at bbb.main(aaa.java:7)
說明問題出在第七行,改後依然如此說明這兩句話都有問題!
我們把它們都註釋掉:
public class aaa{
public static void main(String args[])
{
String s=null;

if(s==null) System.out.println("不如:s==null");
//if(s.length()==0) System.out.println("不如:s。length==0");
//if(s.equals("null")) System.out.println("不如:s。equals null");

}
結果爲:
C:\>javac bbb.java
C:\>java bbb
不如:s==null
這是顯然的!

結論:String s=null;可以和null比較,不能使用String類的所有方法。
問題來了,
s.length()==0和s.equals("null")爲什麼不成立呢?
注意可以編譯通過,只是不能運行。

第四:再來看一組;
public class bbb{
public static void main(String args[])
{
String s=null;

if(s==null) System.out.println("不如:s==null");
if(s=="") System.out.println("不如:s==''");

}
}
結果爲:
不如:s==null
Press any key to continue...

結論:String s=null;可以和null比較,可以和""比較,不可以使用String類的所有方法。

綜上所述:
String s="";可以和null比較,不等;可以和""比較,相等;可以使用String類的所有方法。
String s=null;可以和null比較,相等;可以和""比較,不等;不可以使用String類的所有方法。
jsp的頁面中的表單的值不填返回的是?""還是null呢?經驗證,答案是:""。


第五:下面我們看看在jsp頁面中的這兩種情況!
我們要做的是一個查詢頁面,有三個域分別命名爲bookName、author、publishComm,這三個值可以任意輸入一個,點提交進行查詢。

queryBook.jsp片斷頁面如下:
<body bgcolor="#00ff0f">
<h1 align="center">圖書查詢</h1>
<h2 align="center">請錄入查詢條件:</h2>
<html:form method="post" action="/queryBookAction">
    <table border="0" cellspacing="0" width="100%" id="AutoNumber4" cellpadding="0" style="border-collapse:collapse">
      <tr>
        <td width="31%" align="right" height="34">書名:</td>
        <td height="34" width="69%">
          <html:text property="bookName" size="20">          </html:text>
        </td>
      </tr>
      <tr>
        <td width="31%" align="right" height="17">作者:</td>
        <td height="17" width="69%">
          <html:text property="author" size="20">          </html:text>
        </td>
      </tr>
      <tr>
        <td width="31%" align="right" height="17">出版社:</td>
        <td height="17" width="69%">
          <html:text property="publishComm" size="20">          </html:text>
        </td>
      </tr>
    </table>
    <p align="center">
      <html:submit property="Submit" value=" 提交 "/>
      &nbsp;&nbsp;&nbsp;
      <html:reset property="reset" value=" 重置 "/>
    </p>
</html:form>
</body>
顯然struts表單提交後由queryBookAction.java予以處理。

queryBookAction.java片斷如下:
if (bookName != null) 
        sql = sql + "bookName=" + "'" + bookName + "'";
     else if (author != null) 
        sql = sql + "author=" + "'" + author + "'";
     else if (publishComm != null) 
        sql = sql + "publishComm=" + "'" + publishComm + "'";

結果是無論我們有沒有在bookName中輸入值,第一個if都會被執行,後面的永遠不會被執行,這是爲什麼呢?
情況只有一種:即我們不輸入的時候bookName不是null,而是"",就是說bookName有值只是個空罷了,並不是沒有(即null),
而是有但是等於空,就像數學中的零!
我們不改動jsp頁面,改變queryBookAction.java中的部分內容爲下:
if (bookName.length() != 0) 
        sql = sql + "bookName=" + "'" + bookName + "'";
     else if (author.length() != 0) 
        sql = sql + "author=" + "'" + author + "'";
     else if (publishComm.length() != 0)
        sql = sql + "publishComm=" + "'" + publishComm + "'";
這樣的話就對了!!
同樣的下面的這種寫法也不對,第一個if永遠都會執行,後面的elseif永遠不會執行:
if (bookName != "") 
        sql = sql + "bookName=" + "'" + bookName + "'";
     else if (author != "")
        sql = sql + "author=" + "'" + author + "'";
     else if (publishComm != "") 
        sql = sql + "publishComm=" + "'" + publishComm + "'";
            

---------------------------------------------

牛人們如是說:
String is a very special class in Java!!!   
You can use these two method to create a instance!
But the later ( String s=null ),u can't use String's Methods!
String   abc=null;//聲明瞭一個變量,變量指向null對象,   
String   abc="";//聲明瞭一個變量,變量指向""(空字符串)。   
String   abc=new String("");//聲明瞭一個變量,並參照""(空字符串)構造一個字符串對象,字符長度爲0。   
String   abc;//這個比較特殊,如果用來聲明局部變量,他的值不定,如果是在類實例變量,它同String abc=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的相關方法的時候就會出錯   
第二種則相對簡單,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()方法也不例外,而在方法之外編譯器回自動賦初值。
正如上面舉的那個例子。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章