古之成大事者,不唯有超世之才,亦唯有堅韌不拔之志也!

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            3 隨筆 :: 44 文章 :: 1 評論 :: 0 Trackbacks

          一、創(chuàng)建。
              好了,知道String是非可變類以后,我們可以進(jìn)一步了解String的構(gòu)造方式了。創(chuàng)建一個Stirng對象,主要就有以下兩種方式:

          java 代碼
          1. String str1 = new String("abc");    
          2. Stirng str2 = "abc";  

               雖然兩個語句都是返回一個String對象的引用,但是jvm對兩者的處理方式是不一樣的。對于第一種,jvm會馬上在heap中創(chuàng)建一個String對象,然后將該對象的引用返回給用戶。對于第二種,jvm首先會在內(nèi)部維護(hù)的strings pool中通過String的 equels 方法查找是對象池中是否存放有該String對象,如果有,則返回已有的String對象給用戶,而不會在heap中重新創(chuàng)建一個新的String對象;如果對象池中沒有該String對象,jvm則在heap中創(chuàng)建新的String對象,將其引用返回給用戶,同時將該引用添加至strings pool中。注意:使用第一種方法創(chuàng)建對象時,jvm是不會主動把該對象放到strings pool里面的,除非程序調(diào)用 String的intern方法。看下面的例子:

          java 代碼
          1. String str1 = new String("abc"); //jvm 在堆上創(chuàng)建一個String對象   
          2.   
          3.  //jvm 在strings pool中找不到值為“abc”的字符串,因此   
          4.  //在堆上創(chuàng)建一個String對象,并將該對象的引用加入至strings pool中   
          5.  //此時堆上有兩個String對象   
          6. Stirng str2 = "abc";   
          7.   
          8.  if(str1 == str2){   
          9.          System.out.println("str1 == str2");   
          10.  }else{   
          11.          System.out.println("str1 != str2");   
          12.  }   
          13.   //打印結(jié)果是 str1 != str2,因為它們是堆上兩個不同的對象   
          14.   
          15.   String str3 = "abc";   
          16.  //此時,jvm發(fā)現(xiàn)strings pool中已有“abc”對象了,因為“abc”equels “abc”   
          17.  //因此直接返回str2指向的對象給str3,也就是說str2和str3是指向同一個對象的引用   
          18.   if(str2 == str3){   
          19.          System.out.println("str2 == str3");   
          20.   }else{   
          21.          System.out.println("str2 != str3");   
          22.   }   
          23.  //打印結(jié)果為 str2 == str3  

             再看下面的例子:

          java 代碼
          1. String str1 = new String("abc"); //jvm 在堆上創(chuàng)建一個String對象   
          2.   
          3. str1 = str1.intern();   
          4. //程序顯式將str1放到strings pool中,intern運行過程是這樣的:首先查看strings pool   
          5. //有沒“abc”對象的引用,沒有,則在堆中新建一個對象,然后將新對象的引用加入至   
          6. //strings pool中。執(zhí)行完該語句后,str1原來指向的String對象已經(jīng)成為垃圾對象了,隨時會   
          7. //被GC收集。   
          8.   
          9. //此時,jvm發(fā)現(xiàn)strings pool中已有“abc”對象了,因為“abc”equels “abc”   
          10. //因此直接返回str1指向的對象給str2,也就是說str2和str1引用著同一個對象,   
          11. //此時,堆上的有效對象只有一個。   
          12. Stirng str2 = "abc";   
          13.   
          14.  if(str1 == str2){   
          15.          System.out.println("str1 == str2");   
          16.  }else{   
          17.          System.out.println("str1 != str2");   
          18.  }   
          19.   //打印結(jié)果是 str1 == str2   
          20.   

           

              為什么jvm可以這樣處理String對象呢?就是因為String的非可變性。既然所引用的對象一旦創(chuàng)建就永不更改,那么多個引用共用一個對象時互不影響。


          比如Integer是int包裝類、Float是float的包裝類等等。對這些包裝類的值操作實際上都是通過對其對應(yīng)的基本類型操作而實現(xiàn)的。是不是有 所感悟了?對,String就相當(dāng)于是char[]的包裝類。包裝類的特質(zhì)之一就是在對其值進(jìn)行操作時會體現(xiàn)出其對應(yīng)的基本類型的性質(zhì)。在參數(shù)傳遞時,包 裝類就是如此體現(xiàn)的。所以,對于String在這種情況下的展現(xiàn)結(jié)果的解釋就自然而然得出了。同樣的,Integer、Float等這些包裝類和 String在這種情況下的表現(xiàn)是相同的

          所以如下程序輸出 1234


          public class Test {
          public static void changeStr(String str){
          str
          ="welcome";
          }
          public static void main(String[] args) {
          String str
          ="1234";
          changeStr(str);
          System.out.println(str);
          }
          }



          posted on 2008-07-23 15:58 goto 閱讀(152) 評論(0)  編輯  收藏 所屬分類: JAVA
          主站蜘蛛池模板: 齐齐哈尔市| 南江县| 清水河县| 宁阳县| 闽侯县| 黑河市| 东安县| 尉犁县| 通海县| 寿阳县| 穆棱市| 治县。| 祥云县| 温泉县| 丹阳市| 光山县| 玉林市| 济源市| 乐山市| 惠水县| 蕲春县| 陆丰市| 平顶山市| 九寨沟县| 浦北县| 玉田县| 鄂温| 临高县| 龙山县| 循化| 湘潭市| 嵊州市| 镇巴县| 同江市| 平顶山市| 甘德县| 台中市| 金溪县| 黑水县| 扶风县| 达拉特旗|