前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我说精通字符串,面试官竟然问我 Java 中的 String 有没有长度限制?

我说精通字符串,面试官竟然问我 Java 中的 String 有没有长度限制?

作者头像
淡定的蜗牛
修改2019-10-15 17:50:29
1.2K0
修改2019-10-15 17:50:29
举报
文章被收录于专栏:Java知己Java知己

String 是 Java 中很重要的一个数据类型,除了基本数据类型以外,String 是被使用的最广泛的了,但是,关于 String,其实还是有很多东西容易被忽略的。

就如本文我们要讨论的问题:Java 中的 String 有没有长度限制?

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

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 个字符。如果超过这个个数。就会在编译期报错。

代码语言:txt
复制
public static void main(String[] args) {

          String s = "a...a";

          System.out.println(s.length());

          String s1 = "a...a";

          System.out.println(s1.length());

}

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

代码语言:txt
复制
✗ javac StringLenghDemo.java

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

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

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

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

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

代码语言:txt
复制
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 中也有明确说明:

代码语言:txt
复制
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,这当然也包括字符串的定义咯。

正是金九银十跳槽季,为大家收集了2019年最新的面试资料,有文档、有攻略、有视频。有需要的同学可以在公众号【Java知己】,发送【面试】领取最新面试资料攻略!暗号【1024】千万不要发,否则.....

02 运行期

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

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

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

代码语言:txt
复制
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)

觉得不错的话就点个好看再走呗~

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01 编译期
  • 02 运行期
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档