String 類實現接口屬性一、私有屬性私有類 CaseInsensitiveComparatorString 構造方法一、無參構造函數二、參數爲 String 類型三、參數爲字符數組四、參數爲 int 數組五、參數爲字節數組六、參數爲 StringBuilder 或 StringBuffer七、特殊的 protected 構造方法其餘方法一、concat 鏈接函數二、getBytes三、equals 和 hashCode四、比較方法五、先後綴斷定六、索引獲取七、字符串截取八、字符串替換九、valueOf十、intern()方法參考連接 java
Java 中數據類型分爲兩大類:基礎數據類型(byte,short,int,long,float,double,char,boolean)和引用類型(String 類型和基礎數據類型的包裝類),能夠看出 String 類型是很是特殊的,同時也是編寫代碼過程當中使用比較頻繁的一種類型,爲了更好的瞭解該類型,決心鑽研一下 String 類源碼,但願能有所收穫。web
public final class String implements Serializable, Comparable<String>, CharSequence
複製代碼
從該類的聲明中咱們能夠看出String是final類型的,表示該類不能被繼承,同時該類實現了三個接口。面試
String 的底層是由 char 數組構成的正則表達式
private final char[] value;
private int hash;
複製代碼
因爲底層 char 數組是 final 的,因此 String 對象是不可變的,且不可被繼承。 value:是一個 private
final 修飾的 char 數組,String 類是經過該數組來存在字符串的。 hash:是一個 private 修飾的 int
變量,用來存放 String 對象的 hashCode。數據庫
private staticfinal long serialVersionUID = -6849794470754667710L;
private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
複製代碼
由於String實現了Serializable接口,因此支持序列化和反序列化支持。Java的序列化機制是經過在運行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的字節流中的serialVersionUID與本地相應實體(類)的serialVersionUID進行比較,若是相同就認爲是一致的,能夠進行反序列化,不然就會出現序列化版本不一致的異常(InvalidCastException)。編程
private static class CaseInsensitiveComparator implements Comparator<String>, Serializable
複製代碼
該類一樣實現了 Comparator 和 Serializable 接口,用於 String 類對象的排序。segmentfault
public int compare(String var1, String var2) {
int var3 = var1.length();
int var4 = var2.length();
int var5 = Math.min(var3, var4);
for(int var6 = 0; var6 < var5; ++var6) {
char var7 = var1.charAt(var6);
char var8 = var2.charAt(var6);
if (var7 != var8) {
var7 = Character.toUpperCase(var7);
var8 = Character.toUpperCase(var8);
if (var7 != var8) {
var7 = Character.toLowerCase(var7);
var8 = Character.toLowerCase(var8);
if (var7 != var8) {
return var7 - var8;
}
}
}
}
return var3 - var4;
}
複製代碼
從源碼來看,在該類中存在一個 compare 方法,方法對兩個對象的比較流程以下:循環的次數爲長度最小的字符串的長度;從頭開始比較每一個字符,若是不相等則轉換爲大寫再比較,再不相等轉換爲小寫比較,最後字符之間相減。減法操做會將獲取字符的 hashCode,而後相減(漢字也是如此)。若是循環過程當中字符比較都相等,最後返回兩個字符串對象長度的差值。數組
public String() {
this.value = "".value;
}
複製代碼
String s = new String();
System.out.println(s); //值爲"",也就是空字符串
System.out.println(s.hashCode()); //hash未賦初始值,因此默認值爲0,後期再詳細講hashCode方法
複製代碼
public String(String var1) {
this.value = var1.value;
this.hash = var1.hash;
}
複製代碼
首先聲明一下 Java 的語法是容許在一個類中訪問該類的實例對象的私有屬性的。可是其餘類就不可了。緩存
public String(char[] var1) {
this.value = Arrays.copyOf(var1, var1.length);
}
//var2是字符數組開始截取的位置,從0開始;var3是截取的長度
public String(char[] var1, int var2, int var3) {
if (var2 < 0) {
throw new StringIndexOutOfBoundsException(var2);
} else {
if (var3 <= 0) {
if (var3 < 0) {
throw new StringIndexOutOfBoundsException(var3);
}
if (var2 <= var1.length) {
this.value = "".value;
return;
}
}
if (var2 > var1.length - var3) {
throw new StringIndexOutOfBoundsException(var2 + var3);
} else {
this.value = Arrays.copyOfRange(var1, var2, var2 + var3);
}
}
}
複製代碼
一樣都是用字符數組建立 String,前者是複製完整的字符數組到 String 中的 value 值,後者是從截取字符數組的一部份內容複製到 String 中。使用 Arrays.copyOf 方法或 Arrays.copyOfRange 方法進行復制,建立一個新的字符串對象,隨後修改的字符數組不影響新建立的字符串。安全
public String(int[] var1, int var2, int var3) {
if (var2 < 0) {
throw new StringIndexOutOfBoundsException(var2);
} else {
if (var3 <= 0) {
if (var3 < 0) {
throw new StringIndexOutOfBoundsException(var3);
}
if (var2 <= var1.length) {
this.value = "".value;
return;
}
}
if (var2 > var1.length - var3) {
throw new StringIndexOutOfBoundsException(var2 + var3);
} else {
int var4 = var2 + var3;
int var5 = var3;
int var7;
for(int var6 = var2; var6 < var4; ++var6) {
var7 = var1[var6];
if (!Character.isBmpCodePoint(var7)) {//判斷是否爲負數,正數爲true
if (!Character.isValidCodePoint(var7)) {
throw new IllegalArgumentException(Integer.toString(var7));
}
++var5;
}
}
char[] var10 = new char[var5];
var7 = var2;
for(int var8 = 0; var7 < var4; ++var8) {
int var9 = var1[var7];
if (Character.isBmpCodePoint(var9)) {
var10[var8] = (char)var9;
} else {
Character.toSurrogates(var9, var10, var8++);
}
++var7;
}
this.value = var10;
}
}
}
複製代碼
須要注意的是:做爲參數的 int 數組中值,至少須要知足「大寫字母(A-Z):65 (A)~ 90(Z);小寫字母(a-z):97(a) ~ 122(z);字符數字(‘0’ ~ ‘9’):48(‘0’) ~ 57(‘9’)」的條件。當數組中值爲其餘數字時,獲得的字符串結果可能爲空或特殊符號。
在 Java 中,String 實例中保存有一個 char[] 字符數組,char[] 字符數組是以 unicode 碼來存儲的,String 和 char 爲內存形式。
byte 是網絡傳輸或存儲的序列化形式,因此在不少傳輸和存儲的過程當中須要將 byte[] 數組和 String 進行相互轉化。因此 String 提供了一系列重載的構造方法來將一個字符數組轉化成 String,提到 byte[] 和 String 之間的相互轉換就不得不關注編碼問題。
String(byte[] bytes, Charset charset)
複製代碼
該構造方法是指經過 charset 來解碼指定的 byte 數組,將其解碼成 unicode 的 char[] 數組,構形成新的 String。
這裏的 bytes 字節流是使用 charset 進行編碼的,想要將他轉換成 unicode 的 char[] 數組,而又保證不出現亂碼,那就要指定其解碼方式。
經過字節數組構造 String 有不少形式,會使用 StringCoding.decode 方法進行解碼,按照是否指定解碼方式分的話能夠分爲兩種:
a、
public String(byte[] var1, int var2, int var3) {
checkBounds(var1, var2, var3);
this.value = StringCoding.decode(var1, var2, var3);
}
public String(byte[] var1) {
this((byte[])var1, 0, var1.length);
}
複製代碼
這兩種構造方法沒有指定編碼格式,默認使用 ISO-8859-1 編碼格式進行編碼操做。
static char[] decode(byte[] var0, int var1, int var2) {
String var3 = Charset.defaultCharset().name();
try {
return decode(var3, var0, var1, var2);
} catch (UnsupportedEncodingException var6) {
warnUnsupportedCharset(var3);
try {
return decode("ISO-8859-1", var0, var1, var2);
} catch (UnsupportedEncodingException var5) {
MessageUtils.err("ISO-8859-1 charset not available: " + var5.toString());
System.exit(1);
return null;
}
}
}
複製代碼
b、
String(byte bytes[], Charset charset)
String(byte bytes[], String charsetName)
String(byte bytes[], int offset, int length, Charset charset)
String(byte bytes[], int offset, int length, String charsetName)
複製代碼
當構造方法參數中帶有 charsetName 或者 charset 的時候,使用的解碼的字符集就是咱們指定的 charsetName 或者 charset。
public String(StringBuffer var1) {
synchronized(var1) {
this.value = Arrays.copyOf(var1.getValue(), var1.length());
}
}
public String(StringBuilder var1) {
this.value = Arrays.copyOf(var1.getValue(), var1.length());
}
複製代碼
這兩個構造方法是不多用到的,平時多使用 StringBuffer.toString 方法或者 StringBuilder.toString 方法。其中 StringBuffer.toString 是調用 String(char[] var1, boolean var2)
;而 StringBuilder.toString 則是調用 String(char[] var1, int var2, int var3)
。關於效率問題,Java 的官方文檔有提到說使用 StringBuilder 的 toString 方法會更快一些,緣由是 StringBuffer 的 toString 方法是 synchronized 的,在犧牲了效率的狀況下保證了線程安全。
String(char[] var1, boolean var2) {
this.value = var1;
}
複製代碼
從代碼中咱們能夠看出,該方法和 String(char[] value)有兩點區別:
在網上看到說是有兩點區別,關於第二點區別,關鍵在於調用方調用該構造方法前是怎麼處理的,在 StringBuffer.toString 方法中能夠詳細的看出 new String(char[] var1, boolean var2) 的使用。
public synchronized String toString() {
if (this.toStringCache == null) {
this.toStringCache = Arrays.copyOfRange(this.value, 0, this.count);
}
return new String(this.toStringCache, true);
}
複製代碼
其中 toStringCache 表示緩存,用來保存上一次調用 toString 的結果,若是 value 的字符串序列發生改變,就會將它清空。首先判斷 toStringCache 是否爲 null,若是是先將 value 經過 Arrays.copyOfRange 方法複製到緩存裏,而後使用 toStringCache new一個 String。
綜上,我認爲該構造方法雖然沒法拿來直接使用,但是在別的地方可使用,好比說 StringBuffer.toString 方法中。至於爲什麼要再構建這麼一個特殊的構造方法,而不是直接使用 String(char[] value) 方法,緣由在於 StringBuffer 中的 toStringCache 屬性存在,它的意義不支持在 toString 方法中直接使用 String(char[] value) 方法。(該部分僅爲我的觀點,若有差錯,請指正!)
爲何 Java 會提供這樣一個方法呢?
講到這裏,就須要講下 String 類中還有沒有其餘的方法像這個構造函數那樣「性能好的、節約內存的、安全」。其實在 Java7 以前 String 類中也有不少這樣的方法,好比 substring,replace,concat,valueOf
等方法,實際上它們使用的是 String(int var1, int var2, char[] var3)方法來實現。
可是在 Java 7 以後,substring 已經再也不使用這種「優秀」的方法了,如下是 Java8 中的源碼:
public String substring(int var1) {
if (var1 < 0) {
throw new StringIndexOutOfBoundsException(var1);
} else {
int var2 = this.value.length - var1;
if (var2 < 0) {
throw new StringIndexOutOfBoundsException(var2);
} else {
return var1 == 0 ? this : new String(this.value, var1, var2);
}
}
}
複製代碼
Java8 中 substring 方法涉及到的 new String 源碼以下:
public String(char[] var1, int var2, int var3) {
if (var2 < 0) {
throw new StringIndexOutOfBoundsException(var2);
} else {
if (var3 <= 0) {
if (var3 < 0) {
throw new StringIndexOutOfBoundsException(var3);
}
if (var2 <= var1.length) {
this.value = "".value;
return;
}
}
if (var2 > var1.length - var3) {
throw new StringIndexOutOfBoundsException(var2 + var3);
} else {
this.value = Arrays.copyOfRange(var1, var2, var2 + var3);
}
}
}
複製代碼
會對傳進來的 value 值經過 Arrays.copyOfRange 方法進行拷貝。
反觀 Java6 中 substring 方法涉及到的 new String 源碼以下:
String(int var1, int var2, char[] var3) {
this.value = var3;
this.offset = var1;
this.count = var2;
}
複製代碼
同 new String(char[] var1, boolean var2) 構造函數的第二個特色同樣,構造出來的 String 和參數傳過來的 char[] value 共享同一個數組 。這就可能會形成內存泄漏問題。
看一個例子,假設一個方法從某個地方(文件、數據庫或網絡)取得了一個很長的字符串,而後對其進行解析並提取其中的一小段內容,這種狀況常常發生在網頁抓取或進行日誌分析的時候。
下面是示例代碼:
String aLongString = "...averylongstring...";
String aPart = aLongString .substring(20, 40); //aPart字符串共享aLongString部分數據
return aPart;
複製代碼
在這裏 aLongString 只是臨時的,真正有用的是 aPart,其長度只有 20 個字符,可是它的內部數組倒是從 aLongString 那裏共享的,所以雖然 aLongString 自己能夠被回收,但它的內部數組卻不能釋放。這就致使了內存泄漏。若是一個程序中這種狀況常常發生有可能會致使嚴重的後果,如內存溢出,或性能降低。
新的實現雖然損失了性能,並且浪費了一些存儲空間,但卻保證了字符串的內部數組能夠和字符串對象一塊兒被回收,從而防止發生內存泄漏,所以新的 substring 比原來的更健壯。
length() 返回字符串長度
isEmpty() 返回字符串是否爲空
charAt(int index) 返回字符串中第(index+1)個字符(數組索引)
char[] toCharArray() 轉化成字符數組
trim()去掉兩端空格
toUpperCase()轉化爲大寫
toLowerCase()轉化爲小寫
boolean matches(String regex) 判斷字符串是否匹配給定的regex正則表達式
boolean contains(CharSequence s) 判斷字符串是否包含字符序列 s
String[] split(String regex, int limit) 按照字符 regex將字符串分紅 limit 份
String[] split(String regex) 按照字符 regex 將字符串分段
複製代碼
public String concat(String var1) {
int var2 = var1.length();
if (var2 == 0) {
return this;
} else {
int var3 = this.value.length;
char[] var4 = Arrays.copyOf(this.value, var3 + var2);
var1.getChars(var4, var3);
return new String(var4, true);
}
}
複製代碼
拼接 var1 會生成一個新的字符串對象,對原有字符串無影響。
byte[] getBytes() 使用平臺的默認字符集將此 String 編碼爲 byte 序列,並將結果存儲到一個新的 byte 數組中。
byte[] getBytes(String var1) 使用指定的字符集將此 String 編碼爲 byte 序列,並將結果存儲到一個新的 byte 數組中。
byte[] getBytes(Charset var1) 使用給定的 charset 將此 String 編碼到 byte 序列,並將結果存儲到新的 byte 數組。
void getBytes(int var1, int var2, byte[] var3, int var4) 已過期
複製代碼
值得注意的是,在使用這些方法的時候必定要注意編碼問題。好比:String s = "你好,世界!"; byte[] bytes = s.getBytes();
這段代碼在不一樣的平臺上運行獲得結果是不同的。因爲沒有指定編碼方式,因此在該方法對字符串進行編碼的時候就會使用系統的默認編碼方式。
在中文操做系統中可能會使用 GBK 或者 GB2312 進行編碼,在英文操做系統中有可能使用 iso-8859-1 進行編碼。這樣寫出來的代碼就和機器環境有很強的關聯性了,爲了不沒必要要的麻煩,要指定編碼方式。
public boolean equals(Object var1) {
if (this == var1) {
return true;
} else {
if (var1 instanceof String) {
String var2 = (String)var1;
int var3 = this.value.length;
if (var3 == var2.value.length) {
char[] var4 = this.value;
char[] var5 = var2.value;
for(int var6 = 0; var3-- != 0; ++var6) {
if (var4[var6] != var5[var6]) {
return false;
}
}
return true;
}
}
return false;
}
}
public int hashCode() {
int var1 = this.hash;
if (var1 == 0 && this.value.length > 0) {
char[] var2 = this.value;
for(int var3 = 0; var3 < this.value.length; ++var3) {
var1 = 31 * var1 + var2[var3];
}
this.hash = var1;
}
複製代碼
在 Java 中基於各類數據類型分析 == 和 equals 的區別一節中講到 String 類有重寫本身的 equals 和 hashCode 方法,因此它倆須要一塊兒講述。
首先是 equals 方法,它比較的流程是:字符串對象相同(即自我比較);類型一致且長度相等時,比較字符內容是否相同。
而後是 hashCode 方法,若是 hash 值不等於 0,且 value.length 大於 0,則進行 hash 值計算。這裏重點說下 var1 == 0
這一斷定條件,var1 是一個 int 類型的值,默認值爲 0,所以 0 能夠表示可能未執行過 hash 計算,但不能表示必定未執行過 hash 計算,緣由是咱們如今還不肯定 hash 計算後是否會產生 0 值;
執行 hash 計算後,會不會產生值爲 0 的 hash呢?根據 hash 的計算邏輯,當 val2[0] = 0 時,根據公式 var1 = 31 * var1 + val2[i];
進行計算, var1 的值等於 0。可是通過查詢 ASCII 表發現,null 的 ASCII 值爲 0 。顯然 val2[0]中永遠不可能存放 null,所以 hash 計算後不會產生 0 值, var1== 0 能夠做爲是否進行過 hash 計算的斷定條件。
最後獲得計算公式爲:
val2[0]*31^(n-1) + val2[1]*31^(n-2) + ... + val2[n-1]
複製代碼
爲何要使用這個公式,就是在存儲數據計算 hash 地址的時候,咱們但願儘可能減小有一樣的 hash 地址。若是使用相同 hash 地址的數據過多,那麼這些數據所組成的 hash 鏈就更長,從而下降了查詢效率。
因此在選擇係數的時候要選擇儘可能長的係數而且讓乘法儘可能不要溢出的係數,由於若是計算出來的 hash 地址越大,所謂的「衝突」就越少,查找起來效率也會提升。
選擇31做爲因子的緣由: 爲何 String hashCode 方法選擇數字31做爲乘子
有這樣一道面試題「兩個對象的 hashCode()相同,則 equals()也必定爲 true,對嗎?
」答案:不對,兩個對象的 hashCode()相同,equals()不必定 true。
String str1 = "通話";
String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d", str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));
//結果
str1:1179395 | str2:1179395
false
複製代碼
很顯然「通話」和「重地」的 hashCode() 相同,然而 equals() 則爲 false,由於在散列表中,hashCode()相等即兩個鍵值對的哈希值相等,然而哈希值相等,並不必定能得出鍵值對相等。
boolean equals(Object anObject); 比較對象
boolean contentEquals(StringBuffer sb); 與StringBuffer對象比較內容
boolean contentEquals(CharSequence var1); 與字符比較內容
boolean equalsIgnoreCase(String anotherString);忽略大小寫比較字符串對象
int compareTo(String anotherString); 比較字符串
int compareToIgnoreCase(String str); 忽略大小寫比較字符串
boolean regionMatches(int toffset, String other, int ooffset, int len)局部匹配
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) 可忽略大小寫局部匹配
複製代碼
contentEquals 方法
public boolean contentEquals(CharSequence var1) {
if (var1 instanceof AbstractStringBuilder) {
if (var1 instanceof StringBuffer) {
synchronized(var1) {
return this.nonSyncContentEquals((AbstractStringBuilder)var1);
}
} else {
return this.nonSyncContentEquals((AbstractStringBuilder)var1);
}
} else if (var1 instanceof String) {
return this.equals(var1);
} else {
char[] var2 = this.value;
int var3 = var2.length;
if (var3 != var1.length()) {
return false;
} else {
for(int var4 = 0; var4 < var3; ++var4) {
if (var2[var4] != var1.charAt(var4)) {
return false;
}
}
return true;
}
}
}
複製代碼
String 、StringBuilder、StringBuffer 都實現了 CharSequence 接口,因此上述方法能夠接收這三種類型的參數。另外 StringBuilder、StringBuffer 繼承了 AbstractStringBuilder 父類,因此它倆經過 nonSyncContentEquals 方法進行比較,注意 StringBuffer 須要考慮線程安全,加鎖以後再調用。
compareTo 方法
public int compareTo(String var1) {
int var2 = this.value.length;
int var3 = var1.value.length;
int var4 = Math.min(var2, var3);
char[] var5 = this.value;
char[] var6 = var1.value;
for(int var7 = 0; var7 < var4; ++var7) {
char var8 = var5[var7];
char var9 = var6[var7];
if (var8 != var9) {
return var8 - var9;
}
}
return var2 - var3;
}
複製代碼
經過下面這個例子進行展現:
String s1 = new String("abc");
String s2 = new String("abcdfg");
System.out.println(s2.compareTo(s1)); //3
System.out.println(s1.compareTo(s2)); //-3
s2 = new String("fghjkl");
System.out.println(s2.compareTo(s1)); //5
複製代碼
當兩個對象內容徹底一致時,返回結果爲 0;在字符串最小長度下,若是有不一樣的字符,系統則自動轉換爲 int 類型作差值。
boolean startsWith(String var1, int var2) 測試此字符串從指定索引開始的子字符串是否以指定前綴開始
boolean startsWith(String var1) 測試此字符串是否以指定的前綴開始。
boolean endsWith(String var1) 測試此字符串是否以指定的後綴結束。
複製代碼
int indexOf(int var1) 返回指定字符(int 轉 char)在此字符串中第一次出現處的索引。從0索引開始
int indexOf(int var1, int var2) 返回在此字符串中第一次出現指定字符處的索引,從指定的索引開始搜索。var2 小於字符串的長度
int indexOf(String var1) 返回指定子字符串在此字符串中第一次出現處的索引,從0索引開始。var1必須是此字符串的一個連續子集,不然返回-1
int indexOf(String var1, int var2) 返回指定子字符串在此字符串中第一次出現處的索引,從指定的索引開始。
int lastIndexOf(int var1) 返回指定字符(int 轉 char)在此字符串中最後一次出現處的索引。從0索引開始
int lastIndexOf(int var1, int var2) 返回在此字符串中最後一次出現指定字符處的索引,從指定的索引開始搜索。var2 小於字符串的長度
int lastIndexOf(String var1) 返回指定子字符串在此字符串中最後一次出現處的索引,從0索引開始。var1必須是此字符串的一個連續子集,不然返回-1
int lastIndexOf(String var1, int var2) 返回指定子字符串在此字符串中最後一次出現處的索引,從指定的索引開始。
複製代碼
String substring(int var1) 返回一個新的字符串,它是此字符串的一個子字符串。從var1開始截取,截取長度爲此字符串的長度減去var1
String substring(int var1, int var2) 返回一個新字符串,它是此字符串的一個子字符串。從var1開始截取,截取長度爲var2。
CharSequence subSequence(int var1, int var2) 返回一個新的字符序列,它是此序列的一個子序列。
複製代碼
String replace(char oldChar, char newChar) 返回一個新的字符串,它是經過用 newChar 替換此字符串中出現的全部 oldChar 獲得的。
String replaceFirst(String regex, String replacement) 使用給定的 replacement 替換此字符串匹配給定的正則表達式的第一個子字符串。
String replaceAll(String regex, String replacement) 使用給定的 replacement 替換此字符串全部匹配給定的正則表達式的子字符串。
String replace(CharSequence var1, CharSequence var2) 使用指定的字面值替換序列替換此字符串全部匹配字面值目標序列的子字符串。
複製代碼
public String replace(char var1, char var2) {
if (var1 != var2) {
int var3 = this.value.length;
int var4 = -1;
char[] var5 = this.value;
do {
++var4;
} while(var4 < var3 && var5[var4] != var1);
if (var4 < var3) {
char[] var6 = new char[var3];
for(int var7 = 0; var7 < var4; ++var7) {
var6[var7] = var5[var7];
}
while(var4 < var3) {
char var8 = var5[var4];
var6[var4] = var8 == var1 ? var2 : var8;
++var4;
}
return new String(var6, true);
}
}
return this;
}
複製代碼
replace 的參數能夠是 char 或者 CharSequence,便可以支持字符的替換, 也支持字符串的替換。當參數爲 char 時,是經過本身自定義的方法來更換字符;當參數爲 CharSequence 時,實際調用的是 replaceAll 方法。replaceAll 和 replaceFirst 的參數是 regex,即基於規則表達式的替換。區別是一個所有替換,一個只替換第一個。
static String valueOf(Object var0)
static String valueOf(char[] var0)
static String valueOf(char[] var0, int var1, int var2)
static String valueOf(boolean var0)
static String valueOf(int var0)
static String valueOf(long var0)
static String valueOf(float var0)
static String valueOf(double var0)
複製代碼
valueOf 都是靜態函數,不須要實例化 String 對象,直接調用用於將其餘基本數據類型轉換爲 String 類型。
public native String intern();
複製代碼
intern 方法是 Native 調用,它的做用是在全局字符串常量池裏尋找等值的對象的引用,若是沒有找到則在常量池中存放當前字符串對象的引用並返回該引用,不然直接返回常量池中已存在的 String 對象引用。
intern 方法與常量池有着很大的聯繫,經過學習該方法的使用,便於咱們瞭解內存分配的概念,因此該方法會在後續章節裏詳細講解。想要了解的朋友能夠先了解一下常量池的知識,前往 Java 中方法區與常量池 便可。