posts - 10, comments - 4, trackbacks - 0, articles - 1

          由String中null和""的區別所想到的?

          Posted on 2006-06-06 08:14 yuyu 閱讀(1515) 評論(1)  編輯  收藏

          在驗證一個表單時,如果在服務器端驗證提交過來的值,一般先通過request對象取值,然后驗證,代碼如下:

          ?

          String?val? = ?request.getParameter( " val " );
          ???
          if (val != "" ) {}
          ???
          else {}


          ??如果這樣寫是沒有問題的,但是如果寫成 if(val!=null) 結果就出問題了,結果總是true。

          問題:
          ""和null的區別是什么?
          null表示沒有引用任何對象,那""呢是否是堆中的對象呢?

          對此問題我編寫了一段簡單的代碼進行了判斷:

          public ? class ?TestNull {
          ??
          static ?String?s;
          ??
          public ? static ? void ?main(String?args[]) {
          ?????String?s1
          = null ;
          ?????String?s2
          = "" ;
          ?????String?s3?
          = ? new ?String( "" );

          ?????System.out.println(
          " s: " + s);
          ?????System.out.println(
          " s1: " + s1);
          ?????System.out.println(
          " s2: " + s2);
          ?????System.out.println(
          " s1==s: " + (s1 == s));
          ?????System.out.println(
          " s1==s2: " + (s1 == s2));
          ?????System.out.println(
          " s2==\ " \ " : " + (s2 == "" ));
          ?????System.out.println(
          " s3==s2: " + (s2 == s3));
          ?????System.out.println(
          " s2.equals(s1): " + s2.equals(s1));
          ?????System.out.println(
          " s2.equals(s3): " + s2.equals(s3));?
          ?????System.out.println(s1.equals(s2));???
          // throw??java.lang.NullPointerException
          ???}
          ?
          }


          結果:
          s:null
          s1:null
          s2:
          s1==s:true
          s1==s2:false
          s2=="":true
          s3==s2:false
          s2.equals(s1):false
          s2.equals(s3):true
          Exception in thread "main" java.lang.NullPointerException
          ????????at TestNull.main(TestNull.java:17)

          在這里我們可以很清楚的看到""和null的區別了。
          ""的確是不同于null的,從""可以使用equals()方法我們可以清楚的認識到""是一個堆中值。

          在以上程序中s2和s3用"=="來判斷得到的結果是false,道理很簡單,因為它們的地址是不一樣的。但發現用s2==""的結果是true,以次類推,我們使用if(val!="")的時候,先用的是賦""值給val,然后利用val!=""來判斷。

          由于對jvm不是特別熟悉,所以對String 的存儲總是感覺有問題,String既有值變量的一些特征(只要不new就可以用"=="判斷)又有引用變量的一些方法(利用equals()判斷),所以希望大伙討論下。

          我猜想過程是這樣的,當String s="abcde"的時候,并不是在堆中新開辟空間,而是在棧中開辟,只有這樣當我們才能方便的使用"==",并且當我們再賦值String s1="abcde"以后s1==s為true。但是這樣問題來了,equals()是比較對象的,現在的s,s2根本就不是對象了。著就出現了一個矛盾。
          如果反過來String s="abcde"是在堆中的話,那么當我們String s1="abcde"的時候應該是先在堆中找值為"abcde"的對象,如果沒有、新建,如果有將對象地址給s1。那么如果我們先String s3 = new String("abcde")然后再String s1="abcde"的話,s1==s3應該為true,但是并不是這樣的。很遺憾s1==s3為false,這樣兩種解釋都行不通,那過程到底是怎樣的呢?希望大伙都來討論下。

          Feedback

          # re: 由String中null和""的區別所想到的?  回復  更多評論   

          2011-07-11 11:02 by pkl
          Java虛擬機會維護一個內部的滯留字符串對象的列表(唯一字符串的池)來避免在堆內存中產生重復的String對象 也就是String s="abcde"和String s1="abcde"是相同引用到 "abcde"
          但是String s3 = new String("abcde")創建的"abcde"不會在這個列表里,所以String s2 ="abcde"的時候會找不到已有的而創建新的"abcde"

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 将乐县| 高邑县| 财经| 庆云县| 丹东市| 永安市| 桃园市| 揭西县| 宜兰市| 修水县| 定西市| 大厂| 福州市| 浙江省| 贺州市| 苏尼特右旗| 墨竹工卡县| 界首市| 济南市| 乌什县| 鱼台县| 潍坊市| 朝阳市| 铜鼓县| 樟树市| 军事| 雅江县| 鹤岗市| 金湖县| 尼勒克县| 云梦县| 新竹县| 防城港市| 陈巴尔虎旗| 隆子县| 宁德市| 高密市| 平利县| 盐山县| 乐平市| 余江县|