您的位置 首页 php

面试题01-String是否有长度限制

面试题01-String是否有长度限制

1、场景模拟

自己模拟20万长度的字符,赋值给String报错

检测字符串长度工具()

2、原因分析

1、通过源码分析String应该是由char类型的数组构成

2、如果是char类型的数组那么没有其它限制的情况下String的长度应该为value字符串数组的长度

3、value字符串数组的长度为int类型,那么根据int类型的包装类Integer可以得到如下信息,最大值为2^31-1 但是根据场景模拟结果,显然长度根本没有到2^31-1 就报错了!!!

4、这个时候就必须推出JVM,JVM编译时会将字符串转换为字面量,在编译时将字面量放入常量池中,这时候JVM对字符串会做一些限制

参考Java虚拟机规则#jvms-4.10

所有的常量池的通用规则如下

字符串的规则如下(这里定义的 u2 string_index 表示的是常量池的有效索引,其类型是CONSTANT_Utf8_info 结构体表示的)

那么什么是CONSTANT_Utf8_info规则

在class文件中u2表示的是无符号数占2个字节单位,我们知道1个字节占8位,2个字节就是16位 ,那么2个字节能表示的范围就是2^16- 1 = 65535(定义一组私有数据类型来表示 Class 文件的内容,它们包括 u1,u2 和 u4,分别代表了1、2 和 4 个字节的无符号数 每个 Class 文件都是由 8 字节为单位的字节流组成,所有的 16 位、32 位和 64 位长度的数 据将被构造成 2 个、4 个和 8 个 8 字节单位来表示)

5、综上可以确定字符串的长度是2^16-1了吗?不不不

根据官方解释,就是说数组的有效范围是【0-65535】,但是虚拟机还需要一个字节的指令作为结束符,所有真正有效范围是【0-65534】

注意点:这里的范围仅限编译时期,如果你是运行时拼接的字符串是可以超出这个范围的

 // 也就是说如下情况,编译不报错,运行时拼接字符串是可以超过这个范围
public class StringTest {
    public static void main(String[] args) {
        String result = "";
        for (int i = 0; i <1000_0000_00 ; i++) {
            result+=i;
        }
    }
}
  

3、测试

准备字符为65534的字符串,验证通过

4、结论

通过对字符串的源码分析可知,字符串由字符数据char[ ]构成,由于数组的长度为int类型,而int的包装类是Integer,那么Integer最大的表示值应该为2^31-1, 但是通过翻阅java虚拟机手册可知,class文件格式的定义以及常量池中对String类型的结构体定义我们可以知道对于索引定义了u2,就是无符号占2个字节,2个字节可以表示的最大范围是2^16 -1 = 65535,但虚拟机需要最后一位为结束指令,所以这个范围就是65534。

文章来源:智云一二三科技

文章标题:面试题01-String是否有长度限制

文章地址:https://www.zhihuclub.com/153426.shtml

关于作者: 智云科技

热门文章

网站地图