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

    文章

    2911

    浏览量

    103281
  • 字符串
    +关注

    关注

    1

    文章

    553

    浏览量

    20266
收藏 人收藏

    评论

    相关推荐

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

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

    java环境配置成功后怎么运行

    命令编译Java源文件,生成字节码文件(.class后缀); 使用java命令运行生成的字节码文件。 例如,我们有一
    的头像 发表于 12-06 15:57 689次阅读

    java环境配置成功后能执行哪些操作

    Java环境配置成功后,您可以进行以下操作: 编写和运行Java程序:配置成功后,您可以使用Java编写程序,运行并测试它们。您可以使用任何
    的头像 发表于 12-06 15:55 394次阅读

    idea的java运行配置怎么弄

    Java是一种跨平台的编程语言,可以通过Java虚拟机(JVM)在不同的操作系统和硬件上运行。在运行Java程序之前,需要进行一些配置。本文
    的头像 发表于 12-06 14:04 802次阅读

    eclipse设置java运行环境

    在Eclipse中设置Java运行环境是非常重要的,它能够确保你的代码能够正确地编译运行。下面介绍如何设置Java
    的头像 发表于 12-06 11:29 789次阅读

    eclipse怎么运行java项目

    在Eclipse中运行Java项目是非常简单的。下面了解一下如何在Eclipse中运行Java项目。 首先,确保您已经在Eclipse中创建了Jav
    的头像 发表于 12-06 11:25 1324次阅读

    java怎么限制输入数字的范围

    Java中,你可以使用循环和条件语句来限制输入数字的范围。下面我将详细介绍如何实现这一功能。 首先,你需要使用Java的输入输出库来接收用户的输入。Java中提供了Scanner类来
    的头像 发表于 11-30 16:07 697次阅读

    java switch case 能不能用字符串

    支持也有一些限制。 在使用字符串作为switch语句的表达式时,可以通过使用String类型的值来判断。下面是一个简单的示例,展示了如何在Java中使用字符串的switch语句: String
    的头像 发表于 11-30 14:46 954次阅读

    bigdecimal转string类型避免空指针

    Java中,BigDecimal是用于处理高精度数字计算的类。它提供了一种有效的方法来避免使用浮点数的精确度损失问题。然而,在将BigDecimal对象转换为String类型时,需要特别小心以避
    的头像 发表于 11-30 11:12 1328次阅读

    bigdecimal转string类型

    将BigDecimal转换为String类型是在Java编程中常常遇到的一个问题。BigDecimal是Java中用于表示高精度十进制数的类,而String则是用于表示文本字符串的数据
    的头像 发表于 11-30 11:09 4235次阅读

    为什么要限制变频器与电机之间电缆长度

    为什么要限制变频器与电机之间电缆长度限制变频器与电机之间电缆长度的原因是多方面的。在以下文章中,我将详尽、详实、细致地解释为什么限制电缆
    的头像 发表于 11-06 11:32 1301次阅读

    JDK中java.lang.String 类的源码解析

    1、String 类的定义 public final class String implements java.io.Serializable, Comparable, CharSequence
    的头像 发表于 10-13 10:51 298次阅读
    JDK中<b class='flag-5'>java.lang.String</b> 类的源码解析

    Java和JavaEE都是什么?有什么区别?

    Java分三个版本:Java SE(标准版)、Java EE(企业版)、Java ME(微型版)。 可简单的总结为三点: Java SE 是
    的头像 发表于 10-11 17:01 558次阅读

    Java泛型的背景和作用

    等)只能存储Object类型的对象,这使得在使用集合时需要进行强制类型转换,容易出现类型错误。 泛型的背景:在Java 5版本之前,Java的类型是静态的,在编译时确定,并且在运行时擦
    的头像 发表于 09-20 14:30 580次阅读
    <b class='flag-5'>Java</b>泛型的背景和作用

    Linux内核的编译运行

    想让Linux内核代码跑起来,得先搭建编译运行代码的环境。
    发表于 06-23 11:56 414次阅读
    Linux内核的<b class='flag-5'>编译</b>和<b class='flag-5'>运行</b>