您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    面试官:String长度有限制吗?是多少?还好我看过
    时间:2020-11-10 21:17 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    话说Java中String是有长度限制的,听到这里很多人不由要问,String还有长度限制?是的有,而且在JVM编译中还有标准,而且有的家人们在面试的时分也遇到了,本人就遇到过面试的时分问这个的,而且在之前开发的中也真实地遇到过这个String长度限制的场景(将某固定文件转码成Base64的方式用字符串存储,在运转时需求的时分在转回来,事先文件比较大),那这个标准限制究竟是怎样样的,我们话不多说先䁖䁖去。

    String

    首先要知道String的长度限制我们就需求知道String是怎样存储字符串的,String其实是运用的一个char类型的数组来存储字符串中的字符的。

    面试官:String长度有限制吗?是多少?还好我看过


    存储String的容器原来是它

    那么String既然是数组存储那数组会有长度的限制吗?是的有限制,但是是在有先提条件下的,我们看看String中前往length的办法。

    面试官:String长度有限制吗?是多少?还好我看过


    String类中的length办法

    由此我们看到前往值类型是int类型,Java中定义数组是可以给数组指定长度的,当然不指定的话默许会依据数组元历来指定:

    int[] arr1 = new 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)

    面试官:String长度有限制吗?是多少?还好我看过


    Integer的取值范围

    看到这我们尝试经过编码来验证一下上述观念。

    面试官:String长度有限制吗?是多少?还好我看过


    以字面量方式定义字符串

    以上是我经过定义字面量的方式结构的10万个字符的字符串,编译之后虚拟机提示报错,说我们的字符串长渡过长,不是说好了可以存21亿个吗?为什么才10万个就报错了呢?

    其实这里触及到了JVM编译标准的限制了,其实JVM在编译时,假设我们将字符串定义成了字面量的方式,编译时JVM是会将其寄存在常量池中,这时分JVM对这个常量池存储String类型做出了限制,接上去我们先看下手册是如何说的。

    面试官:String长度有限制吗?是多少?还好我看过


    java虚拟机标准截图

    常量池中,每个 cp_info 项的格式必须相反,它们都以一个表示 cp_info 类型的单字节 “tag”项扫尾。前面 info[]项的内容 由tag 的类型所决议。


    java虚拟机标准手册常量类型表

    我们可以看到 String类型的表示是 CONSTANT_String ,我们来看下CONSTANT_String详细是如何定义的。

    面试官:String长度有限制吗?是多少?还好我看过

    这里定义的 u2 string_index 表示的是常量池的有效索引,其类型是CONSTANT_Utf8_info 结构体表示的,这里我们需求留意的是其中定义的length我们看下面这张图。

    面试官:String长度有限制吗?是多少?还好我看过

    在class文件中u2表示的是无符号数占2个字节单位,我们知道1个字节占8位,2个字节就是16位 ,那么2个字节能表示的范围就是2^16- 1 = 65535 。范中class文件格式对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 < end_pc。

    实践上,end_pc 值本身不属于异常处置器的有效范围这点属于 Java 虚拟机历史上的一个设计缺陷:假设 Java 虚拟机中的一个办法的 code 属性的长度刚好是 65535个字节,并且以一个 1 个字节长度的指令完毕,那么这条指令将不能被异常处置器所处置。不过编译器可以经过限制任何办法、实例初始化办法或类初始化办法的code[]数组最大长度为 65534,这样可以直接补偿这个 BUG。

    (责任编辑:admin)