欢迎来到Introzo百科
Introzo百科
当前位置:网站首页 > 技术 > 【第201期】面试官:String的长度有限制吗?多少?幸运的是,我看到了

【第201期】面试官:String的长度有限制吗?多少?幸运的是,我看到了

日期:2023-10-05 17:24

May 17, 2022 3:59 pm • 面试问题 • 阅读 4 点击上方“Java面试题精选”,关注公众号 面试时画图,查漏补缺 >>番外:往期面试题,10个为单位放在这个公众号菜单栏->面试题,有需要的欢迎阅读 阶段总结合集:一年内容,200道Java面试题阶段总结 前言 据说Java中的String是有长度限制的。听到这里,很多人不禁要问,String有长度限制吗?是的,有,而且JVM编译有规范,有的家人面试的时候也遇到过。 我在面试的时候也被问到过这个问题,而且我在之前的开发中其实也遇到过这种String长度限制的场景(将一个固定的文件转码成Base64的形式并存储为字符串,这需要在运行时进行传回的时候,当时文件比较大),那么这个标准有什么限制呢?让我们深入探讨,不再赘述。 细绳 首先,要知道String的长度限制,我们需要知道String是如何存储字符串的。 String实际上是使用char类型数组来存储字符串中的字符。 存放String的容器原来是 那么既然String存储在数组中,那么数组会不会有长度限制呢?是的,有限制,但有先决条件。我们看一下返回String长度的方法。 String类中的length方法 由此我们看出返回值类型是int类型。在Java中定义数组时,可以指定数组的长度。当然,如果不指定,默认会根据数组元素指定: int[] arr1 = 新 int[10]; // 定义一个长度为10的数组 int[] arr2 = {1,2,3,4,5}; // 那么数组的长度就是5 Java 中整数是有限的。如果我们通过源码查看int类型对应的包装类Integer可以看到最大长度限制为2^31 -1,也就是说数组的长度为0~2^31-1,那么计算结果为(2^31-1 = 2147483647 = 4GB) 整数值范围 看到这里,我们尝试通过编码来验证上述观点。 将字符串定义为文字上面是我通过定义文字构造的一个 100,000 个字符的字符串。编译后,虚拟机提示错误,说我们的字符串长度太长。我们不是说可以存21亿吗?为什么只有10万就报错了? 其实这涉及到JVM编译规范的限制。事实上,当JVM在编译时,如果我们将字符串定义为文字,那么JVM在编译时会将其存储在常量池中。这个时候,JVM就会对String类型的存储进行限制。接下来我们看看说明书上是怎么说的。 java虚拟机规范截图 常量池中的每个 cp_info 条目必须具有相同的格式,以表示 cp_info 类型的单字节“标记”条目开头。以下 info[] 项的内容由标签类型决定。 Java虚拟机规范手册常量类型表 我们可以看到String类型的表示是CONSTANT_String。我们来看看CONSTANT_String具体是如何定义的。 这里定义的u2 string_index表示常量池的有效索引,其类型由CONSTANT_Utf8_info结构体表示。这里需要注意的是其中定义的长度。我们看下面的图片。历史文章:200个阶段的总结 在类文件中,u2代表一个占用2个字节的无符号数。我们知道1字节占8位,2字节占16位。那么2个字节可以表示的范围就是2^16- 1 = 65535。 Fanzhong类文件格式提供了u1和u2定义的总结: 这里总结一下Java虚拟机法规 1.class文件中的文件内容类型说明 定义一组私有数据类型来表示Class文件的内容。它们包括u1、u2和u4,分别代表1、2和4字节的无符号数。 每个Class文件都是由8字节单元的字节流组成,所有16位、32位、64位长度的数据都会被构造成2、4、8个8字节单元来表示。 2、程序异常处理的有效范围说明 start_pc和end_pc的值表示code[]数组中异常处理程序的有效范围。start_pc 必须是当前 code[] 数组中指令操作码的有效索引,end_pc 是当前 code[] 数组中指令操作码的有效索引,或者等于 code_length 的值,即当前code[ ]数组的长度。 start_pc 的值必须小于 end_pc。 当程序计数器在[start_pc, end_pc)范围内时,异常处理程序将生效。即令x为异常处理程序有效范围内的值,并且x满足:start_pc≤x

关灯