java-不可变字符串

一個字串物件一旦被配置,它的內容就是固定不可變的(immutable),例如下面這個宣告:
String str = "caterpillar";

這個宣告會配置一個長度為11的字串物件,您無法改變它的內容;別以為下面這個宣告就是改變一個字串物件的內容:
String str = "just";
str = "justin";

事實上,在這個程式片段中,會有兩個字串物件,一個是"just",長度為4,一個是"justin",長度為6,它們兩個是不同的字串物件,您並不是在 "just"字串後加上"in"字串,而是讓str名稱參考至新的字串物件,如下所示:
原來參考至此
str --------> "just"

重新指定後

str ---------> "justin"
參考新的字串物件

在Java中,使用 = 將一個字串物件指定給一個名稱,其意義為改變名稱的參考物件,原來的字串物件若沒有其它名稱來參考它,就會在適當的時機被Java的「垃圾回收」(Garbage collection)機制回收,在Java中,程式設計人員通常不用關心無用物件的資源釋放問題,Java會檢查物件是否不再被參考,如果沒有任何名稱參考的物件將會被回收。

如果您在程式中使用下面的方式來宣告,則實際上是指向同一個字串物件:
String str1 = "flyweight";
String str2 = "flyweight";
System.out.println(str1 == str2);

程式的執行結果會顯示true,在Java中,會維護一個String Pool,對於一些可以共享的字串物件,會先在String Pool中查找是否存在相同的String內容(字元相同),如果有就直接傳回,而不是直接創造一個新的String物件,以減少記憶體的耗用。

再來個一看例子,String的intern()方法,來看看它的API說明的節錄:
Returns a canonical representation for the string object.

A pool of strings, initially empty, is maintained privately by the class String.

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

這段話其實說明了 Flyweight 模式 的運作方式,來用個實例來說明會更清楚:

  • StringIntern.java
public class StringIntern { 
    public static void main(String[] args) { 
        String str1 = "fly"; 
        String str2 = "weight"; 
        String str3 = "flyweight"; 
        String str4; 

        str4 = str1 + str2; 
        System.out.println(str3 == str4); 

        str4 = (str1 + str2).intern(); 
        System.out.println(str3 == str4); 
    } 
} 


在程式中第一次比較str3與str4物件是否為同一物件時,您知道結果會是false,而intern()方法會先檢查 String Pool中是否存在字元部份相同的字串物件,如果有的話就傳回,由於程式中之前已經有"flyweight"字串物件,intern()在String Pool中發現了它,所以直接傳回,這時再進行比較,str3與str4所指向的其實是同一物件,所以結果會是true。

注意到了嗎?== 運算在Java中被用來比較兩個名稱是否參考至同一物件,所以不可以用==來比較兩個字串的內容是否相同,例如:
String str1 = new String("caterpillar");
String str2 = new String("caterpillar");
System.out.println(str1 == str2);

上面會顯示false的結果,因為str1與str2是分別參考至不同的字串物件,如果要比較兩個(字串)物件是否相同,您要使用equals()方法,例如:
String str1 = new String("caterpillar");
String str2 = new String("caterpillar");
System.out.println(str1.equals(str2));

這樣子結果才會顯示所想要的比較結果:true。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值