微信知彼網(wǎng)絡(luò)網(wǎng)站建設(shè)電商網(wǎng)站開發(fā)平臺
String在java中我們是用來操作字符串的,但它的底層結(jié)構(gòu)確是一個char[]數(shù)組,通過數(shù)組的方式將每個字符進(jìn)行保存。
使用時:String str="ABCD",內(nèi)部存value確是:value=['A','B','C','D'];
如下圖:
參考String源碼如下:
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {private final char value[];private int hash; // Default to 0private static final long serialVersionUID = -6849794470754667710L;......此處省略N多代碼public String(String original) {this.value = original.value;this.hash = original.hash;} }
通過源碼中的構(gòu)造方法可以看到,我們傳遞的參數(shù)值 是直接賦值給了value。如果聲明一個String a=”ABCD”,那a對象的value實際就是一個數(shù)組[A,B,C,D]
String賦值有兩種,一種是“=”直接賦值,另一種是new String("xxx")賦值,這兩種是有區(qū)別的。
- “=”賦值不會在堆上創(chuàng)建新的對象,而是在常量池中搜索,如果常量池中有這個字符串則直接引用這個字符串的地址。如果沒有這個字符,則會在常量池中創(chuàng)建該字符串,并引用地址,字符常量池中不存在兩個相同的字符串,也就是說
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2);//true
//二者引用的地址是相同的,都指向一個字符串
- new String()意味著創(chuàng)建了一個新的對象,會在堆上分配一塊內(nèi)存,但并不是說這個字符就存儲在了堆上,而是存儲了一個地址,這個地址仍然指向字符常量池。
String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1==str2);//false
繼續(xù)看下列問題
聲明四個String對象如下,思考下它們之間用?== 比較的結(jié)果?
String a= “abc”;
String b = “abc”;
String c = new String(“abc”);
String d = “ab” + “c”;
????????其中a,b,d所有他們的引用是一樣的,所以String 沒有被新創(chuàng)建對象。所以他們?nèi)齻€用 == 對比是true。 而c 則是new(“abc”) 新建了一個String 對象,值雖然一樣,但是與 a,b,d 引用不一樣,所以a,b,d 與 c 對比則是 false。
String a="a"+"b"+"c"在內(nèi)存中創(chuàng)建幾個對象?
????????這個問題涉及到了字符串常量池和字符串拼接,String a="a"+"b"+"c" 通過編譯器優(yōu)化后,得到的效果是 String a="abc"。此時,如果字符串常量池中存在abc,則該語句并不會創(chuàng)建對象,只是將字符串常量池中的引用返回而已。如果字符串常量池中不存在abc,則會創(chuàng)建并放入字符串常量池,并返回引用,此時會有一個對象進(jìn)行創(chuàng)建。
JDK9為何要將String底層由char[]改成了byte[]?
?對于JDK9后的版本,String底層由char[]改成了byte。那么將char[]改成了byte有和意義呢?
1)節(jié)省內(nèi)存:char占用兩個字節(jié),byte只需要一個字節(jié)。
那么問題來了,如果存儲英文或數(shù)字可以使用byte,那存儲的中文或特殊字符呢?
源碼內(nèi)有一個:private final byte coder;用于兼容兩個字節(jié)的字符
private final byte coder;static final byte LATIN1 =0 ;// LATIN1用單個字節(jié)來表示字符
static final byte UTF16 =1; // UTF16 是用雙字節(jié)來表示字符
?所以就可以根據(jù)存儲內(nèi)容的不同,去判斷應(yīng)該使用那種編碼,如中文時使用UTF16,英文就可以是LATIN1
2)減少GC的次數(shù):減少了內(nèi)存使用之后,必然垃圾回收次數(shù)也會相對應(yīng)減少?