面試官:String長(zhǎng)度有限制嗎?是多少?
300本計(jì)算機(jī)編程的經(jīng)典書(shū)籍下載
AI全套:Python3+TensorFlow打造人臉識(shí)別智能小程序
最新人工智能資料-Google工程師親授 Tensorflow-入門(mén)到進(jìn)階
黑馬頭條項(xiàng)目 - Java Springboot2.0(視頻、資料、代碼和講義)14天完整版
來(lái)自:toutiao.com/i6893014573322863111
前言
話說(shuō)Java中String是有長(zhǎng)度限制的,聽(tīng)到這里很多人不禁要問(wèn),String還有長(zhǎng)度限制?是的有,而且在JVM編譯中還有規(guī)范,而且有的家人們?cè)诿嬖嚨臅r(shí)候也遇到了,本人就遇到過(guò)面試的時(shí)候問(wèn)這個(gè)的,而且在之前開(kāi)發(fā)的中也真實(shí)地遇到過(guò)這個(gè)String長(zhǎng)度限制的場(chǎng)景(將某固定文件轉(zhuǎn)碼成Base64的形式用字符串存儲(chǔ),在運(yùn)行時(shí)需要的時(shí)候在轉(zhuǎn)回來(lái),當(dāng)時(shí)文件比較大),那這個(gè)規(guī)范限制到底是怎么樣的,咱們?cè)挷欢嗾f(shuō)先??去。
String

那么String既然是數(shù)組存儲(chǔ)那數(shù)組會(huì)有長(zhǎng)度的限制嗎?是的有限制,但是是在有先提條件下的,我們看看String中返回length的方法。

int[] arr1 = new int[10];// 定義一個(gè)長(zhǎng)度為10的數(shù)組
int[] arr2 = {1,2,3,4,5}; // 那么此時(shí)數(shù)組的長(zhǎng)度為5

看到這我們嘗試通過(guò)編碼來(lái)驗(yàn)證一下上述觀點(diǎn)。

以上是我通過(guò)定義字面量的形式構(gòu)造的10萬(wàn)個(gè)字符的字符串,編譯之后虛擬機(jī)提示報(bào)錯(cuò),說(shuō)我們的字符串長(zhǎng)度過(guò)長(zhǎng),不是說(shuō)好了可以存21億個(gè)嗎?為什么才10萬(wàn)個(gè)就報(bào)錯(cuò)了呢?搜索公眾號(hào)互聯(lián)網(wǎng)架構(gòu)師回復(fù)“2T”,送你一份驚喜禮包。


我們可以看到 String類型的表示是 CONSTANT_String ,我們來(lái)看下CONSTANT_String具體是如何定義的。


這里對(duì)java虛擬機(jī)規(guī)摘要部分
1、class文件中文件內(nèi)容類型解釋
定義一組私有數(shù)據(jù)類型來(lái)表示 Class 文件的內(nèi)容,它們包括 u1,u2 和 u4,分別代
表了 1、2 和 4 個(gè)字節(jié)的無(wú)符號(hào)數(shù)。
每個(gè) Class 文件都是由 8 字節(jié)為單位的字節(jié)流組成,所有的 16 位、32 位和 64 位長(zhǎng)度的數(shù)
據(jù)將被構(gòu)造成 2 個(gè)、4 個(gè)和 8 個(gè) 8 字節(jié)單位來(lái)表示。2、程序異常處理的有效范圍解釋
start_pc 和 end_pc 兩項(xiàng)的值表明了異常處理器在 code[]數(shù)組中的有效范圍。
start_pc 必須是對(duì)當(dāng)前 code[]數(shù)組中某一指令的操作碼的有效索引,end_pc 要
么是對(duì)當(dāng)前 code[]數(shù)組中某一指令的操作碼的有效索引,要么等于 code_length
的值,即當(dāng)前 code[]數(shù)組的長(zhǎng)度。start_pc 的值必須比 end_pc 小。
當(dāng)程序計(jì)數(shù)器在范圍[start_pc, end_pc)內(nèi)時(shí),異常處理器就將生效。即設(shè) x 為
異常句柄的有效范圍內(nèi)的值,x 滿足:start_pc ≤ x < end_pc。
實(shí)際上,end_pc 值本身不屬于異常處理器的有效范圍這點(diǎn)屬于 Java 虛擬機(jī)歷史上
的一個(gè)設(shè)計(jì)缺陷:如果 Java 虛擬機(jī)中的一個(gè)方法的 code 屬性的長(zhǎng)度剛好是 65535
個(gè)字節(jié),并且以一個(gè) 1 個(gè)字節(jié)長(zhǎng)度的指令結(jié)束,那么這條指令將不能被異常處理器
所處理。不過(guò)編譯器可以通過(guò)限制任何方法、實(shí)例初始化方法或類初始化方法的
code[]數(shù)組最大長(zhǎng)度為 65534,這樣可以間接彌補(bǔ)這個(gè) BUG。搜索公眾號(hào)互聯(lián)網(wǎng)架構(gòu)師回復(fù)“2T”,送你一份驚喜禮包。 注意:這里對(duì)個(gè)人認(rèn)為比較重要的點(diǎn)做了標(biāo)記,首先第一個(gè)加粗說(shuō)白了就是說(shuō)數(shù)組有效范圍就是【0-65565】但是第二個(gè)加粗的地方又解釋了,因?yàn)樘摂M機(jī)還需要1個(gè)字節(jié)的指令作為結(jié)束,所以其實(shí)真正的有效范圍是【0-65564】,這里要注意這里的范圍僅限編譯時(shí)期,如果你是運(yùn)行時(shí)拼接的字符串是可以超出這個(gè)范圍的。




看到這里我們來(lái)總結(jié)一下:
問(wèn):字符串有長(zhǎng)度限制嗎?是多少?
但是通過(guò)翻閱java虛擬機(jī)手冊(cè)對(duì)class文件格式的定義以及常量池中對(duì)String類型的結(jié)構(gòu)體定義我們可以知道對(duì)于索引定義了u2,就是無(wú)符號(hào)占2個(gè)字節(jié),2個(gè)字節(jié)可以表示的最大范圍是2^16 -1 = 65535。
其實(shí)是65535,但是由于JVM需要1個(gè)字節(jié)表示結(jié)束指令,所以這個(gè)范圍就為65534了。超出這個(gè)范圍在編譯時(shí)期是會(huì)報(bào)錯(cuò)的,但是運(yùn)行時(shí)拼接或者賦值的話范圍是在整形的最大范圍。
解析到這里就告一段落了,如果覺(jué)得在下講得對(duì)你有幫助的可以點(diǎn)一波贊或者在看,如果發(fā)現(xiàn)有講的不好的或者有什么遺漏的,歡迎評(píng)論區(qū)留言相互學(xué)習(xí)交流。
全棧架構(gòu)社區(qū)交流群
?「全棧架構(gòu)社區(qū)」建立了讀者架構(gòu)師交流群,大家可以添加小編微信進(jìn)行加群。歡迎有想法、樂(lè)于分享的朋友們一起交流學(xué)習(xí)。
看完本文有收獲?請(qǐng)轉(zhuǎn)發(fā)分享給更多人
Flutter 移動(dòng)應(yīng)用開(kāi)發(fā)實(shí)戰(zhàn) 視頻(開(kāi)發(fā)你自己的抖音APP) Java面試進(jìn)階訓(xùn)練營(yíng) 第2季(分布式篇) Java高級(jí) - 分布式系統(tǒng)開(kāi)發(fā)技術(shù)視頻
2019最新Python視頻:從入門(mén)到Swiper項(xiàng)目實(shí)戰(zhàn)
2019年Android應(yīng)用程序開(kāi)發(fā)
2019重磅高級(jí)資源:Java并發(fā)編程原理和實(shí)戰(zhàn)
最新黑馬大數(shù)據(jù)資源:深入解析docker容器化技術(shù)
最新Java后端實(shí)戰(zhàn)視頻:SSM框架在線商城系統(tǒng)
2019最新黑客技術(shù)之Windows網(wǎng)絡(luò)安全精講
2019最新Python實(shí)戰(zhàn)視頻:Python+Django項(xiàng)目實(shí)
黑馬 - Python數(shù)據(jù)結(jié)構(gòu)與算法系列課程
