java.lang(String)
阿新 • • 發佈:2017-08-27
每次 訪問 pat abc 文件路徑 .net copy itl near
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 == b
1. 什麽是不可變類
所謂不可變類,就是創建該類的實例後,該實例的屬性是不可改變的,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)