??初看到這個(gè)問(wèn)題心里還是有點(diǎn)尷尬的,平時(shí)確實(shí)沒(méi)注意過(guò)String最大能有多長(zhǎng)。想要知道String到底有多長(zhǎng),只能從源碼層面來(lái)找答案了兔毙。
??Java中String不是基本數(shù)據(jù)類型,而是引用類型并且是final兄春。String定義為final的原因:
??高效性
??JVM在查找字符串的時(shí)候可以直接定位到String類中澎剥,更準(zhǔn)確的說(shuō)String不可變,才能實(shí)現(xiàn)常量池赶舆。
??安全性
??定義成final哑姚,不能被繼承和修改,可以防止在子類或者其他地方被修改芜茵,導(dǎo)致隱藏Bug產(chǎn)生叙量。
??上面提到常量池,JVM創(chuàng)建對(duì)象是需要開(kāi)銷的九串,為了提高性能绞佩,對(duì)字符串使用字符串常量池進(jìn)行了優(yōu)化,每當(dāng)我們創(chuàng)建一個(gè)字符串時(shí)蒸辆,Jvm先去字符串常量池檢查征炼,如果字符串常量池存在析既,直接返回實(shí)例引用躬贡;否則創(chuàng)建實(shí)例,并存入字符串常量池中眼坏。
??比如常見(jiàn)的判斷:
String a="hello";
String b="hello";
因?yàn)閍和b都是指向"hello"這個(gè)常量池中的常量拂玻,即同一個(gè)地址所以a==b 為true
String c=new String("hello");
因?yàn)閏是new了一個(gè)新對(duì)象酸些,且對(duì)象是在堆上存放,所以c==a為false檐蚜,雖然c的內(nèi)容是創(chuàng)建在堆中魄懂,但是他的內(nèi)部value還是指向JVM常量池的hello的value,它構(gòu)造hello時(shí)所用的參數(shù)依然是hello字符串常量闯第。
??下面正式進(jìn)入今天的主題了填帽,String的最大長(zhǎng)度到底是多大呢?
??翻開(kāi)String類的源碼咙好,你會(huì)看到:
// private final char value[];
private final int count;
public int length() {
final boolean STRING_COMPRESSION_ENABLED = true;
if (STRING_COMPRESSION_ENABLED) {
// For the compression purposes (save the characters as 8-bit if all characters
// are ASCII), the least significant bit of "count" is used as the compression flag.
return (count >>> 1);
} else {
return count;
}
}
可以看到String的length是通過(guò)count值返回的篡腌,count是int型,最大為231-1勾效,所以String理論上最大長(zhǎng)度為231-1嘹悼,2147483647。
但是由于String底層是通過(guò)char[]字符數(shù)組來(lái)實(shí)現(xiàn)层宫,char占用兩個(gè)字節(jié)杨伙,2147483647 個(gè) char 類型就是 4294967294 字節(jié),這接近于 4GB 大小萌腿,想要申請(qǐng)這么一大塊連續(xù)的內(nèi)存空間缀台,失敗也就不足為奇了,所以和電腦的硬件條件有關(guān)哮奇。
??總結(jié)
??String 的最大長(zhǎng)度也就是字符數(shù)組的最大長(zhǎng)度膛腐,理論上最大長(zhǎng)度為 int 類型的最大值,即 2147483647鼎俘。
??在實(shí)際中哲身,一般可獲取的最大值小于理論最大值。