0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Java的String编译期和运行期的长度限制

汽车玩家 来源:未知 作者:李威 2020-05-03 18:02 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

这个问题要分两个阶段看,分别是编译期和运行期。不同的时期限制不一样。

01 编译期

首先,我们先来合理的推断一下,当我们在代码中使用String s = "";的形式来定义String对象的时候,""中字符的个数有没有限制呢?

既然是合理的推断,那就要要足够的依据,所以我们可以从String的源码入手,根据public String(char value[], int offset, int count)的定义,count是int类型的,所以,char value[]中最多可以保存Integer.MAX_VALUE个,即2147483647字符。(jdk1.8.0_73)

但是,实验证明,String s = "";中,最多可以有65534个字符。如果超过这个个数。就会在编译期报错。

public static void main(String[] args) {

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

以上代码,会在String s1 = "a...a";// 共65535个a处编译失败:

javac StringLenghDemo.java
StringLenghDemo.java:11: 错误: 常量字符串过长

明明说好的长度限制是2147483647,为什么65535个字符就无法编译了呢?

当我们使用字符串字面量直接定义String的时候,是会把字符串在常量池中存储一份的。那么上面提到的65534其实是常量池的限制。

常量池中的每一种数据项也有自己的类型。Java中的UTF-8编码的Unicode字符串在常量池中以CONSTANT_Utf8类型表示。

CONSTANTUtf8info是一个CONSTANTUtf8类型的常量池数据项,它存储的是一个常量字符串。常量池中的所有字面量几乎都是通过CONSTANTUtf8info描述的。CONSTANTUtf8_info的定义如下:

CONSTANT_Utf8_info {

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

由于本文的重点并不是CONSTANTUtf8info的介绍,这里就不详细展开了,我们只需要我们使用字面量定义的字符串在class文件中,是使用CONSTANTUtf8info存储的,而CONSTANTUtf8info中有u2 length;表明了该类型存储数据的长度。

u2是无符号的16位整数,因此理论上允许的的最大长度是2^16=65536。而 java class 文件是使用一种变体UTF-8格式来存放字符的,null 值使用两个 字节来表示,因此只剩下 65536- 2 = 65534个字节。

关于这一点,在the class file format spec中也有明确说明:

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.

也就是说,在Java中,所有需要保存在常量池中的数据,长度最大不能超过65535,这当然也包括字符串的定义咯。

02 运行期

上面提到的这种String长度的限制是编译期的限制,也就是使用String s= "";这种字面值方式定义的时候才会有的限制。

那么。String在运行期有没有限制呢,答案是有的,就是我们前文提到的那个Integer.MAX_VALUE ,这个值约等于4G,在运行期,如果String的长度超过这个范围,就可能会抛出异常。(在jdk 1.9之前)

int 是一个 32 位变量类型,取正数部分来算的话,他们最长可以有

2^31-1 =2147483647 个 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)
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    20

    文章

    3006

    浏览量

    116832
  • 字符串
    +关注

    关注

    1

    文章

    596

    浏览量

    23212
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    瑞芯微(EASY EAI)RV1126B 开发(编译)方式说明

    1.交叉编译(推荐)1.1优缺点优点:采用x86架构的CPU进行编译编译速度快。源码编辑方便,开发环境支持各种如vsCode、qtCreator等IDE。缺点:编译环境需要进行安装部
    的头像 发表于 03-28 16:08 5208次阅读
    瑞芯微(EASY EAI)RV1126B 开发(<b class='flag-5'>编译</b>)方式说明

    SGM2527可编程电流限制开关:特性与应用解析

    Corp推出的一款紧凑型电子保险丝(eFuse),具备一套完整的保护功能。 文件下载: SGM2527.pdf 产品概述 SGM2527专为多种流行的直流总线设计,具有宽工作电压范围。其集成的保护N沟道MOSFET具有极低的 (R {DS(ON)}) ,有助于降低正常运行期间的功率损耗。可编程软启动时间可在电源
    的头像 发表于 03-24 11:20 155次阅读

    以太网跳线长度和弯曲程度:如何影响网络性能

    铜缆以太网线在现代企业网络、数据中心和智能制造中仍然发挥着不可替代的作用。以太网铜缆的长度和曲率决定了链路性能、误码率、传输稳定性以及网络带宽。随着线缆长度的增加,其插入损耗也会增加。过大的曲率会
    的头像 发表于 03-24 10:41 168次阅读

    简单高效的鸿蒙编译提速技巧

    在鸿蒙应用开发中编译构建是开发者最频繁的操作,每一次编译提速都能显著提升项目整体开发效率。本次分享几个简单却高效的鸿蒙编译提速技巧,从编译配置、构建方式等维度进行优化,让你的开发流程更
    的头像 发表于 03-04 16:09 254次阅读
    简单高效的鸿蒙<b class='flag-5'>编译</b>提速技巧

    开源鸿蒙技术大会2025丨编译器与编程语言分论坛:语言驱动系统创新,编译赋能生态繁荣

    在万物智联的时代背景下,操作系统底层能力的构建离不开编程语言与编译器的关键支撑。作为开源鸿蒙生态的核心技术,语言设计与编译器、虚拟机实现的进步直接关系到开发效率、运行性能与系统安全。本次分论坛聚焦
    的头像 发表于 11-20 17:24 1166次阅读
    开源鸿蒙技术大会2025丨<b class='flag-5'>编译</b>器与编程语言分论坛:语言驱动系统创新,<b class='flag-5'>编译</b>赋能生态繁荣

    Arm Neoverse CPU上大代码量Java应用的性能测试

    Java 是互联网领域广泛使用的编程语言。Java 应用的一些特性使其性能表现与提前编译的原生应用(例如 C 程序)大相径庭。由于 Java 字节码无法直接在 CPU 上执行,因此通常
    的头像 发表于 11-05 11:25 938次阅读
    Arm Neoverse CPU上大代码量<b class='flag-5'>Java</b>应用的性能测试

    关于伺服电缆长度问题的详解

    伺服电缆作为工业自动化系统中的关键组件,其长度问题直接影响设备性能与系统稳定性。本文将围绕伺服电缆长度对信号传输、电磁干扰、电压降及安装维护的影响展开深度解析,并提供专业解决方案。 一、电缆长度
    的头像 发表于 11-01 07:40 1384次阅读

    riscv virt64编译后 ls无法运行怎么解决?

    用仓库里的默认配置编译qemu-virt64-riscv 生成后运行,显示 [E/DBG] virtio-blk0 mount failed ls看不到文件夹 msh />ls No such directory
    发表于 09-22 06:38

    Java效率提升指南:5个Java工具选型建议及Perforce JRebel和XRebel介绍

    企业级Java环境越来越复杂,真正的破局点,可能不在“人”,而在于“工具”。5个实用建议,帮你理清Java工具的选型思路。
    的头像 发表于 09-11 13:59 1914次阅读
    <b class='flag-5'>Java</b>效率提升指南:5个<b class='flag-5'>Java</b>工具选型建议及Perforce JRebel和XRebel介绍

    cJSON_Parse返回为空,有长度限制是什么原因?

    cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); } 我用的是CJSON软件包 为什么这里解析的json长度限制,怎么去扩大它的
    发表于 09-11 06:28

    如何使TC1796运行在RAM?

    生成工具:DAvE2 目前我用同一份代码,在HighTec选择iROM的情况下,去进行编译调试,可以正常的运行; 但在选择iRAM的情况下,去编译调试,调试日志显示无法读取DBGSR,这应该是出现了程序跑飞了; 从调试界面看,
    发表于 08-13 07:26

    STM32 CubeIDE编译运行(烧录程序)的快捷键是什么?

    CubeIDE编译运行(烧录程序)的快捷键是什么?
    发表于 07-25 07:04

    六类线永久链路的长度不能超过多少米-科兰

    ) 指综合布线系统中固定安装的部分,包括水平电缆、连接模块(如信息插座、配线架)及中间连接点(CP点),不包括两端跳线、测试设备插接件。其长度限制旨在确保信号传输质量,避免因链路过长导致衰减、串扰等问题。 信道(Channel) 包含永久链路及两端跳线(如设备跳线、工作区
    的头像 发表于 07-14 10:09 1878次阅读
    六类线永久链路的<b class='flag-5'>长度</b>不能超过多少米-科兰

    ArkUI-X平台桥接Bridge说明

    \\\\ java.util.HashMap NSDictionary 说明 1、S表示string、number、boolean类型; 2、Record表示<key, value>类型,key仅为string类型
    发表于 06-19 23:12

    Java开发者必备的效率工具——Perforce JRebel是什么?为什么很多Java开发者在用?

    Perforce JRebel是一款Java开发效率工具,旨在帮助java开发人员更快地编写更好的应用程序。JRebel可即时重新加载对代码的修改,无需重启或重新部署应用程序,就能让开发者即时看到代码更改的效果,从而缩短开发、调试和测试周期,大大提升开发效率。
    的头像 发表于 04-27 13:44 979次阅读
    <b class='flag-5'>Java</b>开发者必备的效率工具——Perforce JRebel是什么?为什么很多<b class='flag-5'>Java</b>开发者在用?