String是Java中很重要的一個(gè)數(shù)據(jù)類型,除了基本數(shù)據(jù)類型以外,String是被運(yùn)用的最廣泛的了,可是,關(guān)于String,其實(shí)仍是有很多東西容易被疏忽的。
就如本文咱們要評論的問題:Java中的String有沒有長度約束?
這個(gè)問題要分兩個(gè)階段看,分別是編譯期和運(yùn)行期。不同的時(shí)期約束不一樣。
01編譯期
首要,咱們先來合理的揣度一下,當(dāng)咱們在代碼中運(yùn)用Strings=””;的方法來界說String對象的時(shí)候,””中字符的個(gè)數(shù)有沒有約束呢?
既然是合理的揣度,那就要要足夠的依據(jù),所以咱們能夠從String的源碼入手,依據(jù)publicString(charvalue[],intoffset,intcount)的界說,count是int類型的,所以,charvalue[]中最多能夠保存Integer.MAX_VALUE個(gè),即2147483647字符。(jdk1.8.0_73)
可是,實(shí)驗(yàn)證明,Strings=””;中,最多能夠有65534個(gè)字符。假如超越這個(gè)個(gè)數(shù)。就會在編譯期報(bào)錯(cuò)。
publicstaticvoidmain(String[]args){
Strings=”a…a”;
System.out.println(s.length());
Strings1=”a…a”;
System.out.println(s1.length());
}
以上代碼,會在Strings1=”a…a”;//共65535個(gè)a處編譯失利:
?javacStringLenghDemo.javaStringLenghDemo.java:11:錯(cuò)誤:常量字符串過長
明明說好的長度約束是2147483647,為什么65535個(gè)字符就無法編譯了呢?
當(dāng)咱們運(yùn)用字符串字面量直接界說String的時(shí)候,是會把字符串在常量池中存儲一份的。那么上面說到的65534其實(shí)是常量池的約束。
常量池中的每一種數(shù)據(jù)項(xiàng)也有自己的類型。Java中的UTF-8編碼的Unicode字符串在常量池中以CONSTANT_Utf8類型表示。
CONSTANTUtf8info是一個(gè)CONSTANTUtf8類型的常量池?cái)?shù)據(jù)項(xiàng),它存儲的是一個(gè)常量字符串。常量池中的一切字面量簡直都是經(jīng)過CONSTANTUtf8info描繪的。CONSTANTUtf8_info的界說如下:
CONSTANT_Utf8_info{u1tag;u2length;u1bytes[length];
}
由于本文的要點(diǎn)并不是CONSTANTUtf8info的介紹,這兒就不具體展開了,咱們只需要咱們運(yùn)用字面量界說的字符串在class文件中,是運(yùn)用CONSTANTUtf8info存儲的,而CONSTANTUtf8info中有u2length;表明了該類型存儲數(shù)據(jù)的長度。
u2是無符號的16位整數(shù),因而理論上允許的的最大長度是2^16=65536。而javaclass文件是運(yùn)用一種變體UTF-8格局來寄存字符的,null值運(yùn)用兩個(gè)字節(jié)來表示,因而只剩下65536-2=65534個(gè)字節(jié)。
關(guān)于這一點(diǎn),在theclassfileformatspec中也有清晰說明:
Thelengthoffieldandmethodnames,fieldandmethoddescriptors,andotherconstantstringvaluesislimitedto65535charactersbythe16-bitunsignedlengthitemoftheCONSTANTUtf8infostructure(§4.4.7).Notethatthelimitisonthenumberofbytesintheencodingandnotonthenumberofencodedcharacters.UTF-8encodessomecharactersusingtwoorthreebytes.Thus,stringsincorporatingmultibytecharactersarefurtherconstrained.
也便是說,在Java中,一切需要保存在常量池中的數(shù)據(jù),長度最大不能超越65535,這當(dāng)然也包含字符串的界說咯。
02運(yùn)行期
上面說到的這種String長度的約束是編譯期的約束,也便是運(yùn)用Strings=””;這種字面值方法界說的時(shí)候才會有的約束。
那么。String在運(yùn)行期有沒有約束呢,答案是有的,便是咱們前文說到的那個(gè)Integer.MAX_VALUE,這個(gè)值約等于4G,在運(yùn)行期,假如String的長度超越這個(gè)規(guī)模,就可能會拋出異常。(在jdk1.9之前)
int是一個(gè)32位變量類型,取正數(shù)部分來算的話,他們最長能夠有
2^31-1=2147483647個(gè)16-bitUnicodecharacter2147483647*16=34359738352位34359738352/8=4294967294(Byte)4294967294/1024=4194303.998046875(KB)4194303.998046875/1024=4095.9999980926513671875(MB)4095.9999980926513671875/1024=3.99999999813735485076904296875(GB)
覺得不錯(cuò)的話就點(diǎn)個(gè)美觀再走唄~
廣州天河區(qū)珠江新城富力盈力大廈北塔2706
020-38013166(網(wǎng)站咨詢專線)
400-001-5281 (售后服務(wù)熱線)
深圳市坂田十二橡樹莊園F1-7棟
Site/ http://www.szciya.com
E-mail/ itciya@vip.163.com
品牌服務(wù)專線:400-001-5281
長沙市天心區(qū)芙蓉中路三段398號新時(shí)空大廈5樓
聯(lián)系電話/ (+86 0731)88282200
品牌服務(wù)專線/ 400-966-8830
旗下運(yùn)營網(wǎng)站:
Copyright ? 2016 廣州思洋文化傳播有限公司,保留所有權(quán)利。 粵ICP備09033321號