0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Java的String編譯期和運(yùn)行期的長(zhǎng)度限制

汽車(chē)玩家 ? 來(lái)源:未知 ? 作者:李威 ? 2020-05-03 18:02 ? 次閱讀

這個(gè)問(wèn)題要分兩個(gè)階段看,分別是編譯期和運(yùn)行期。不同的時(shí)期限制不一樣。

01 編譯期

首先,我們先來(lái)合理的推斷一下,當(dāng)我們?cè)诖a中使用String s = "";的形式來(lái)定義String對(duì)象的時(shí)候,""中字符的個(gè)數(shù)有沒(méi)有限制呢?

既然是合理的推斷,那就要要足夠的依據(jù),所以我們可以從String的源碼入手,根據(jù)public String(char value[], int offset, int count)的定義,count是int類(lèi)型的,所以,char value[]中最多可以保存Integer.MAX_VALUE個(gè),即2147483647字符。(jdk1.8.0_73)

但是,實(shí)驗(yàn)證明,String s = "";中,最多可以有65534個(gè)字符。如果超過(guò)這個(gè)個(gè)數(shù)。就會(huì)在編譯期報(bào)錯(cuò)。

public static void main(String[] args) {

          String s = "a...a";// 共65534個(gè)a
          System.out.println(s.length());
          String s1 = "a...a";// 共65535個(gè)a
          System.out.println(s1.length());
}

以上代碼,會(huì)在String s1 = "a...a";// 共65535個(gè)a處編譯失敗:

? javac StringLenghDemo.java
StringLenghDemo.java:11: 錯(cuò)誤: 常量字符串過(guò)長(zhǎng)

明明說(shuō)好的長(zhǎng)度限制是2147483647,為什么65535個(gè)字符就無(wú)法編譯了呢?

當(dāng)我們使用字符串字面量直接定義String的時(shí)候,是會(huì)把字符串在常量池中存儲(chǔ)一份的。那么上面提到的65534其實(shí)是常量池的限制。

常量池中的每一種數(shù)據(jù)項(xiàng)也有自己的類(lèi)型。Java中的UTF-8編碼的Unicode字符串在常量池中以CONSTANT_Utf8類(lèi)型表示。

CONSTANTUtf8info是一個(gè)CONSTANTUtf8類(lèi)型的常量池?cái)?shù)據(jù)項(xiàng),它存儲(chǔ)的是一個(gè)常量字符串。常量池中的所有字面量幾乎都是通過(guò)CONSTANTUtf8info描述的。CONSTANTUtf8_info的定義如下:

CONSTANT_Utf8_info {

     u1 tag;
     u2 length;
     u1 bytes[length];
}

由于本文的重點(diǎn)并不是CONSTANTUtf8info的介紹,這里就不詳細(xì)展開(kāi)了,我們只需要我們使用字面量定義的字符串在class文件中,是使用CONSTANTUtf8info存儲(chǔ)的,而CONSTANTUtf8info中有u2 length;表明了該類(lèi)型存儲(chǔ)數(shù)據(jù)的長(zhǎng)度。

u2是無(wú)符號(hào)的16位整數(shù),因此理論上允許的的最大長(zhǎng)度是2^16=65536。而 java class 文件是使用一種變體UTF-8格式來(lái)存放字符的,null 值使用兩個(gè) 字節(jié)來(lái)表示,因此只剩下 65536- 2 = 65534個(gè)字節(jié)。

關(guān)于這一點(diǎn),在the class file format spec中也有明確說(shuō)明:

The length of field and method names, field and method descriptors, and other constant string values is limited to 65535 characters by the 16-bit unsigned length item of the CONSTANTUtf8info structure (§4.4.7). Note that the limit is on the number of bytes in the encoding and not on the number of encoded characters. UTF-8 encodes some characters using two or three bytes. Thus, strings incorporating multibyte characters are further constrained.

也就是說(shuō),在Java中,所有需要保存在常量池中的數(shù)據(jù),長(zhǎng)度最大不能超過(guò)65535,這當(dāng)然也包括字符串的定義咯。

02 運(yùn)行期

上面提到的這種String長(zhǎng)度的限制是編譯期的限制,也就是使用String s= "";這種字面值方式定義的時(shí)候才會(huì)有的限制。

那么。String在運(yùn)行期有沒(méi)有限制呢,答案是有的,就是我們前文提到的那個(gè)Integer.MAX_VALUE ,這個(gè)值約等于4G,在運(yùn)行期,如果String的長(zhǎng)度超過(guò)這個(gè)范圍,就可能會(huì)拋出異常。(在jdk 1.9之前)

int 是一個(gè) 32 位變量類(lèi)型,取正數(shù)部分來(lái)算的話,他們最長(zhǎng)可以有

2^31-1 =2147483647 個(gè) 16-bit Unicodecharacter
2147483647 * 16 = 34359738352 位
34359738352 / 8 = 4294967294 (Byte)
4294967294 / 1024 = 4194303.998046875 (KB)
4194303.998046875 / 1024 = 4095.9999980926513671875 (MB)
4095.9999980926513671875 / 1024 = 3.99999999813735485076904296875 (GB)
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2970

    瀏覽量

    104834
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    579

    瀏覽量

    20549
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    對(duì)比Python與Java編程語(yǔ)言

    使得編寫(xiě)代碼更加靈活,但也可能導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。 Java 語(yǔ)法相對(duì)冗長(zhǎng),需要顯式聲明變量類(lèi)型,增加了代碼的可讀性和安全性。 靜態(tài)類(lèi)型系統(tǒng)在編譯時(shí)進(jìn)行類(lèi)型檢查,減少了運(yùn)行時(shí)錯(cuò)誤。 二、性
    的頭像 發(fā)表于 11-15 09:31 ?343次閱讀

    了解電源模塊運(yùn)行限制

    電子發(fā)燒友網(wǎng)站提供《了解電源模塊運(yùn)行限制.pdf》資料免費(fèi)下載
    發(fā)表于 09-24 11:13 ?0次下載
    了解電源模塊<b class='flag-5'>運(yùn)行</b><b class='flag-5'>限制</b>

    java編譯能拿到源碼嗎

    在語(yǔ)法和風(fēng)格上有所不同的代碼,因?yàn)樗鼈冎饕P(guān)注于恢復(fù)代碼的邏輯結(jié)構(gòu),而不是精確復(fù)制原始代碼的每個(gè)細(xì)節(jié)。 1. 反編譯的基本原理 Java程序在編譯時(shí),源代碼(.java文件)會(huì)被
    的頭像 發(fā)表于 09-02 11:03 ?1048次閱讀

    java編譯的代碼可以修改么

    Java編譯是一種將編譯后的Java字節(jié)碼(.class文件)轉(zhuǎn)換回源代碼的過(guò)程。反編譯后的代碼可以進(jìn)行修改,但是需要注意,反
    的頭像 發(fā)表于 09-02 11:00 ?722次閱讀

    華納云:java web和java有什么區(qū)別java web和java有什么區(qū)別

    的平臺(tái),Java可以用于開(kāi)發(fā)桌面應(yīng)用程序、移動(dòng)應(yīng)用程序、企業(yè)級(jí)應(yīng)用程序等。 – Java Web是Java語(yǔ)言在Web開(kāi)發(fā)領(lǐng)域的應(yīng)用,它使用Java技術(shù)來(lái)構(gòu)建動(dòng)態(tài)的Web應(yīng)用程序,這些
    的頭像 發(fā)表于 07-16 13:35 ?830次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區(qū)別<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么區(qū)別

    hdmi線長(zhǎng)度不能超過(guò)多少米

    HDMI線長(zhǎng)度限制主要與其版本和實(shí)際應(yīng)用場(chǎng)景中的信號(hào)衰減有關(guān)。以下是對(duì)HDMI線長(zhǎng)度限制的詳細(xì)解釋?zhuān)?HDMI 1.3版本: 最長(zhǎng)長(zhǎng)度:2
    的頭像 發(fā)表于 06-24 10:17 ?8689次閱讀

    為什么我的項(xiàng)目Debug運(yùn)行沒(méi)問(wèn)題,編譯成Release包就報(bào)錯(cuò)?

    引言 在Android開(kāi)發(fā)中,debug包和release包的行為差異可能導(dǎo)致release包在運(yùn)行時(shí)出現(xiàn)問(wèn)題,而這些問(wèn)題在debug包中不會(huì)出現(xiàn)。 本文主要介紹debug包和release包的差異
    的頭像 發(fā)表于 06-12 11:18 ?1002次閱讀
    為什么我的項(xiàng)目Debug<b class='flag-5'>運(yùn)行</b>沒(méi)問(wèn)題,<b class='flag-5'>編譯</b>成Release包就報(bào)錯(cuò)?

    如何利用實(shí)時(shí)示波器測(cè)量線纜長(zhǎng)度

    在電子工程、通信和自動(dòng)化控制等領(lǐng)域,線纜長(zhǎng)度的準(zhǔn)確測(cè)量對(duì)于保證系統(tǒng)的正常運(yùn)行至關(guān)重要。實(shí)時(shí)示波器作為一種功能強(qiáng)大的電子測(cè)量工具,除了能夠觀測(cè)和分析各種波形信號(hào)外,結(jié)合時(shí)域反射(Time-Domain
    的頭像 發(fā)表于 05-27 16:24 ?1432次閱讀

    基于DE1-SOC的String Art實(shí)現(xiàn)

    String Art起源于19世紀(jì)的數(shù)學(xué)家Mary Everest Boole的設(shè)計(jì),隨后發(fā)展成一種利用釘子和線進(jìn)行作畫(huà)的藝術(shù),主要是通過(guò)線的稠密度來(lái)表現(xiàn)不同的圖案。
    的頭像 發(fā)表于 04-09 11:02 ?505次閱讀
    基于DE1-SOC的<b class='flag-5'>String</b> Art實(shí)現(xiàn)

    鴻蒙TypeScript學(xué)習(xí)第10天:【String(字符串)】

    String 對(duì)象用于處理文本(字符串)。
    的頭像 發(fā)表于 04-08 14:32 ?837次閱讀
    鴻蒙TypeScript學(xué)習(xí)第10天:【<b class='flag-5'>String</b>(字符串)】

    【AWTK開(kāi)源智能串口屏方案】MCU SDK使用與編譯運(yùn)行

    本篇文章將介紹AWTK-HMI中的MCU端開(kāi)發(fā)方法,包括MCUSDK常用API的說(shuō)明、使用流程及如何編譯到Linux和STM32平臺(tái)。引言:AWTK-HMI是基于AWTK與AWTK-MVVM開(kāi)發(fā)的低
    的頭像 發(fā)表于 02-19 12:11 ?1236次閱讀
    【AWTK開(kāi)源智能串口屏方案】MCU SDK使用與<b class='flag-5'>編譯</b><b class='flag-5'>運(yùn)行</b>

    使用Tasking編譯器生成的map文件中沒(méi)有變量的字節(jié)長(zhǎng)度,這個(gè)怎么解決?

    使用Tasking編譯器生成的map文件中沒(méi)有變量的字節(jié)長(zhǎng)度,請(qǐng)問(wèn)這個(gè)怎么解決?
    發(fā)表于 02-04 09:24

    在長(zhǎng)時(shí)間運(yùn)行期間控制器如何適應(yīng)PMSM的電機(jī)參數(shù)變化?

    你好,我正在為PMSM設(shè)計(jì)控制器,我有一個(gè)問(wèn)題,在長(zhǎng)時(shí)間運(yùn)行期間,控制器如何適應(yīng)PMSM的電機(jī)參數(shù)變化?
    發(fā)表于 01-22 06:35

    XMC Pinout Tool是否可以不受限制地使用免費(fèi)的Java版本運(yùn)行?

    我有幾個(gè)關(guān)于 XMC 引腳排列工具的問(wèn)題。 首先我想問(wèn)一下 XMC Pinout Tool 是否可以不受限制地使用免費(fèi)的 Java 版本(Oracle Java SE v17 LTS)運(yùn)行
    發(fā)表于 01-22 06:18

    FlashDB在運(yùn)行期間,如果發(fā)現(xiàn)存在壞塊flash會(huì)進(jìn)行隔離處理嗎?

    FlashDB在運(yùn)行期間,如果發(fā)現(xiàn)存在壞塊flash會(huì)進(jìn)行隔離處理嗎? FlashDB是一種在運(yùn)行期間可以進(jìn)行壞塊隔離處理的數(shù)據(jù)庫(kù)系統(tǒng)。在本文中,我將詳細(xì)介紹FlashDB的相關(guān)特性、壞塊處理機(jī)
    的頭像 發(fā)表于 01-17 11:05 ?2552次閱讀