標籤:cep 數組 private nat bounds except 建構函式 fbo sed
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; private int hash; // Default to 0 public String() { //無參構造器 this.value = new char[0]; } public String(String original) { this.value = original.value; this.hash = original.hash; }/*****傳入一個字元數組的建構函式,使用java.utils包中的Arrays類複製******/ public String(char value[]) { this.value = Arrays.copyOf(value, value.length); }/*******傳入一個字串數字,和開始元素,元素個數的建構函式******/ public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count); }/*********************類似方法不介紹了**************************/ public String(StringBuffer buffer) { synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } } public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String) anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }/***********s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]*********/ public int hashCode() { int h = hash;/***如果hash沒有被計算過,並且字串不為空白,則進行hashCode計算*****/ if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
/***intern方法是Native調用,它的作用是在方法區中的常量池裡通過equals方法尋找等值的對象,如果沒有找到則在常量池中
開闢一片空間存放字串並返回該對應String的引用,否則直接返回常量池中已存在String對象的引用。*****/ public native String intern();
舉例:
String a = "abc";String b = new String("ab1").intern();if ( a == b ) { System.out.println("a == b"); } else { System.out.println("a不等於b");}列印出:a == b1. 什麼是不可變類
所謂不可變類,就是建立該類的執行個體後,該執行個體的屬性是不可改變的,Java提供的封裝類和java.lang.String類都是不可變類。當建立它們的執行個體後,其執行個體的屬性是不可改變的。
需要注意的是,對於如下代碼
String s="abc";s="def";
你可能會感到疑惑,不是說String是不可變類嗎,這怎麼可以改變呢,平常我也是這樣用的啊。請注意,s是字串對象的”abc”引用,即引用是可以變化的,跟對象執行個體的屬性變化沒有什麼關係,這點請注意區分。
2.String類被設計成不可變的原因
- 字串常量池的需要
- 允許String對象緩衝HashCode
Java中String對象的雜湊碼被頻繁地使用, 比如在hashMap 等容器中。
字串不變性保證了hash碼的唯一性,因此可以放心地進行緩衝.這也是一種效能最佳化手段,意味著不必每次都去計算新的雜湊碼.
安全性:String被許多的Java類(庫)用來當做參數,例如 網路連接地址URL,檔案路徑path,還有反射機制所需要的String參數等, 假若String不是固定不變的,將會引起各種安全隱患。
- 安全執行緒:因為字串是不可變的,所以是多安全執行緒的,同一個字串執行個體可以被多個線程共用。這樣便不用因為安全執行緒問題而使用同步。字串自己便是安全執行緒的。
3. 如何?一個不可變類
既然不可變類有這麼多優勢,那麼我們借鑒String類的設計,自己實現一個不可變類。
不可變類的設計通常要遵循以下幾個原則:
- 將類聲明為final,所以它不能被繼承。
- 將所有的成員聲明為私人的,這樣就不允許直接存取這些成員。
- 對變數不要提供setter方法。
- 將所有可變的成員聲明為final,這樣只能對它們賦值一次。
- 通過構造器初始化所有成員,進行深拷貝(deep copy)。
- 在getter方法中,不要直接返回對象本身,而是複製對象,並返回對象的拷貝。
java.lang(String)