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
    +关注

    关注

    19

    文章

    2970

    浏览量

    104809
  • 字符串
    +关注

    关注

    1

    文章

    579

    浏览量

    20536
收藏 人收藏

    评论

    相关推荐

    对比Python与Java编程语言

    使得编写代码更加灵活,但也可能导致运行时错误。 Java 语法相对冗长,需要显式声明变量类型,增加了代码的可读性和安全性。 静态类型系统在编译时进行类型检查,减少了运行时错误。 二、性
    的头像 发表于 11-15 09:31 333次阅读

    了解电源模块运行限制

    电子发烧友网站提供《了解电源模块运行限制.pdf》资料免费下载
    发表于 09-24 11:13 0次下载
    了解电源模块<b class='flag-5'>运行</b><b class='flag-5'>限制</b>

    java编译能拿到源码吗

    在语法和风格上有所不同的代码,因为它们主要关注于恢复代码的逻辑结构,而不是精确复制原始代码的每个细节。 1. 反编译的基本原理 Java程序在编译时,源代码(.java文件)会被
    的头像 发表于 09-02 11:03 1040次阅读

    java编译的代码可以修改么

    Java编译是一种将编译后的Java字节码(.class文件)转换回源代码的过程。反编译后的代码可以进行修改,但是需要注意,反
    的头像 发表于 09-02 11:00 709次阅读

    华纳云:java web和java有什么区别java web和java有什么区别

    的平台,Java可以用于开发桌面应用程序、移动应用程序、企业级应用程序等。 – Java Web是Java语言在Web开发领域的应用,它使用Java技术来构建动态的Web应用程序,这些
    的头像 发表于 07-16 13:35 822次阅读
    华纳云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么区别<b class='flag-5'>java</b> web和<b class='flag-5'>java</b>有什么区别

    hdmi线长度不能超过多少米

    HDMI线长度限制主要与其版本和实际应用场景中的信号衰减有关。以下是对HDMI线长度限制的详细解释: HDMI 1.3版本: 最长长度:2
    的头像 发表于 06-24 10:17 8601次阅读

    为什么我的项目Debug运行没问题,编译成Release包就报错?

    引言 在Android开发中,debug包和release包的行为差异可能导致release包在运行时出现问题,而这些问题在debug包中不会出现。 本文主要介绍debug包和release包的差异
    的头像 发表于 06-12 11:18 987次阅读
    为什么我的项目Debug<b class='flag-5'>运行</b>没问题,<b class='flag-5'>编译</b>成Release包就报错?

    如何利用实时示波器测量线缆长度

    在电子工程、通信和自动化控制等领域,线缆长度的准确测量对于保证系统的正常运行至关重要。实时示波器作为一种功能强大的电子测量工具,除了能够观测和分析各种波形信号外,结合时域反射(Time-Domain
    的头像 发表于 05-27 16:24 1417次阅读

    基于DE1-SOC的String Art实现

    String Art起源于19世纪的数学家Mary Everest Boole的设计,随后发展成一种利用钉子和线进行作画的艺术,主要是通过线的稠密度来表现不同的图案。
    的头像 发表于 04-09 11:02 502次阅读
    基于DE1-SOC的<b class='flag-5'>String</b> Art实现

    鸿蒙TypeScript学习第10天:【String(字符串)】

    String 对象用于处理文本(字符串)。
    的头像 发表于 04-08 14:32 832次阅读
    鸿蒙TypeScript学习第10天:【<b class='flag-5'>String</b>(字符串)】

    【AWTK开源智能串口屏方案】MCU SDK使用与编译运行

    本篇文章将介绍AWTK-HMI中的MCU端开发方法,包括MCUSDK常用API的说明、使用流程及如何编译到Linux和STM32平台。引言:AWTK-HMI是基于AWTK与AWTK-MVVM开发的低
    的头像 发表于 02-19 12:11 1233次阅读
    【AWTK开源智能串口屏方案】MCU SDK使用与<b class='flag-5'>编译</b><b class='flag-5'>运行</b>

    使用Tasking编译器生成的map文件中没有变量的字节长度,这个怎么解决?

    使用Tasking编译器生成的map文件中没有变量的字节长度,请问这个怎么解决?
    发表于 02-04 09:24

    在长时间运行期间控制器如何适应PMSM的电机参数变化?

    你好,我正在为PMSM设计控制器,我有一个问题,在长时间运行期间,控制器如何适应PMSM的电机参数变化?
    发表于 01-22 06:35

    XMC Pinout Tool是否可以不受限制地使用免费的Java版本运行

    我有几个关于 XMC 引脚排列工具的问题。 首先我想问一下 XMC Pinout Tool 是否可以不受限制地使用免费的 Java 版本(Oracle Java SE v17 LTS)运行
    发表于 01-22 06:18

    FlashDB在运行期间,如果发现存在坏块flash会进行隔离处理吗?

    FlashDB在运行期间,如果发现存在坏块flash会进行隔离处理吗? FlashDB是一种在运行期间可以进行坏块隔离处理的数据库系统。在本文中,我将详细介绍FlashDB的相关特性、坏块处理机
    的头像 发表于 01-17 11:05 2538次阅读