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

          在驗(yàn)證一個(gè)表單時(shí),如果在服務(wù)器端驗(yàn)證提交過(guò)來(lái)的值,一般先通過(guò)request對(duì)象取值,然后驗(yàn)證,代碼如下:

          ?

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


          ??如果這樣寫(xiě)是沒(méi)有問(wèn)題的,但是如果寫(xiě)成 if(val!=null) 結(jié)果就出問(wèn)題了,結(jié)果總是true。

          問(wèn)題:
          ""和null的區(qū)別是什么?
          null表示沒(méi)有引用任何對(duì)象,那""呢是否是堆中的對(duì)象呢?

          對(duì)此問(wèn)題我編寫(xiě)了一段簡(jiǎn)單的代碼進(jìn)行了判斷:

          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
          ???}
          ?
          }


          結(jié)果:
          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的區(qū)別了。
          ""的確是不同于null的,從""可以使用equals()方法我們可以清楚的認(rèn)識(shí)到""是一個(gè)堆中值。

          在以上程序中s2和s3用"=="來(lái)判斷得到的結(jié)果是false,道理很簡(jiǎn)單,因?yàn)樗鼈兊牡刂肥遣灰粯拥摹5l(fā)現(xiàn)用s2==""的結(jié)果是true,以次類(lèi)推,我們使用if(val!="")的時(shí)候,先用的是賦""值給val,然后利用val!=""來(lái)判斷。

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

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

          Feedback

          # re: 由String中null和""的區(qū)別所想到的?  回復(fù)  更多評(píng)論   

          2011-07-11 11:02 by pkl
          Java虛擬機(jī)會(huì)維護(hù)一個(gè)內(nèi)部的滯留字符串對(duì)象的列表(唯一字符串的池)來(lái)避免在堆內(nèi)存中產(chǎn)生重復(fù)的String對(duì)象 也就是String s="abcde"和String s1="abcde"是相同引用到 "abcde"
          但是String s3 = new String("abcde")創(chuàng)建的"abcde"不會(huì)在這個(gè)列表里,所以String s2 ="abcde"的時(shí)候會(huì)找不到已有的而創(chuàng)建新的"abcde"

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 苏尼特左旗| 富蕴县| 和平县| 安西县| 焉耆| 姚安县| 龙泉市| 安乡县| 琼海市| 南和县| 镇江市| 峡江县| 当阳市| 湖南省| 清流县| 曲周县| 六盘水市| 姚安县| 漳浦县| 涟水县| 积石山| 英德市| 黄浦区| 定西市| 茌平县| 斗六市| 蒙城县| 银川市| 卢湾区| 远安县| 温宿县| 五寨县| 樟树市| 琼海市| 遵义县| 剑川县| 峨眉山市| 祁连县| 贵南县| 桑日县| 康马县|