Java中string的特性

superxgl發表於2011-10-11

 一、建立。

  好了,知道String是非可變類以後,我們可以進一步瞭解String的構造方式了。建立一個Stirng物件,主要就有以下兩種方式:

  java 程式碼

  1.String str1 = new String("abc");

  2.Stirng str2 = "abc";

  雖然兩個語句都是返回一個String物件的引用,但是jvm對兩者的處理方式是不一樣的。對於第一種,jvm會馬上在heap中建立一個String物件,然後將該物件的引用返回給使用者。對於第二種,jvm首先會在內部維護的strings pool中通過String的 equels 方法查詢是物件池中是否存放有該String物件,如果有,則返回已有的String物件給使用者,而不會在heap中重新建立一個新的String物件;如果物件池中沒有該String物件,jvm則在heap中建立新的String物件,將其引用返回給使用者,同時將該引用新增至strings pool中。注意:使用第一種方法建立物件時,jvm是不會主動把該物件放到strings pool裡面的,除非程式呼叫 String的intern方法。看下面的例子:

  java 程式碼

  1.String str1 = new String("abc"); //jvm 在堆上建立一個String物件

  2.

  3.//jvm 在strings pool中找不到值為“abc”的字串,因此

  4.//在堆上建立一個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.  //列印結果是 str1 != str2,因為它們是堆上兩個不同的物件

  14.

  15.  String str3 = "abc";

  16.//此時,jvm發現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.//列印結果為 str2 == str3

  再看下面的例子:

  java 程式碼

  1.String str1 = new String("abc"); //jvm 在堆上建立一個String物件

  2.

  3.str1 = str1.intern();

  4.//程式顯式將str1放到strings pool中,intern執行過程是這樣的:首先檢視strings pool

  5.//有沒“abc”物件的引用,沒有,則在堆中新建一個物件,然後將新物件的引用加入至

  6.//strings pool中。執行完該語句後,str1原來指向的String物件已經成為垃圾物件了,隨時會

  7.//被GC收集。

  8.

  9.//此時,jvm發現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.  //列印結果是 str1 == str2

  20.

  為什麼jvm可以這樣處理String物件呢?就是因為String的非可變性。既然所引用的物件一旦建立就永不更改,那麼多個引用共用一個物件時互不影響。

  比如Integer是int包裝類、Float是float的包裝類等等。對這些包裝類的值操作實際上都是通過對其對應的基本型別操作而實現的。是不是有所感悟了?對,String就相當於是char[]的包裝類。包裝類的特質之一就是在對其值進行操作時會體現出其對應的基本型別的性質。在引數傳遞時,包裝類就是如此體現的。所以,對於String在這種情況下的展現結果的解釋就自然而然得出了。同樣的,Integer、Float等這些包裝類和 String在這種情況下的表現是相同的

  所以如下程式輸出 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);

  }

  }


相關文章