Java中String字符串长度

String类是Java中最为常用的类,我们知道String是个final类,不能修改内容。但是String类型是否有长度限制呢,下面来一探究竟。

想要搞清楚这个问题,首先我们需要翻阅一下String 的源码,看下其中是否有关于长度的限制或者定义。String 类中有很多重载的构造函数,其中有几个是支持用户传入length 来执行长度的:

    public String(byte bytes[], int offset, int length) {
        checkBounds(bytes, offset, length);
        this.value = StringCoding.decode(bytes, offset, length);
    }

可以看到,这里面的参数length是使用int 类型定义的,那么也就是说,String 定义的时候,最大支持的长度就是int 的最大范围值。int类型占4个字节,可以得出最大长度=2^31 - 1。所以从String构造方法来看,这是不是就是String支持的最大长度了呢?

其实并不是,这个值只是在运行期,我们构造String 的时候可以支持的一个最大长度,
而实际上,在编译期,定义字符串的时候也是有长度限制的,下面通过代码来展示下。

        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 100000; i++) {
            stringBuilder.append("A");
        }

        String result = stringBuilder.toString();
        System.out.println(result);

在这里插入图片描述
这里可以看到result被赋予10万长度的字符串是没有报错的。接着换一种赋值方式:

        // 10万长度的AAA赋值
        String result = "AAAA...AAA";
        System.out.println(result);

在这里插入图片描述
那么,明明String 的构造函数指定的长度是可以支持2147483647(2^31 - 1)的,为什么像以上形式定义的时候无法编译呢?其实,形如String s = “xxx”;定义String 的时候,xxx 被我们称之为字面量,这种字
面量在编译之后会以常量的形式进入到Class 常量池。那么问题就来了,因为要进入常量池,就要遵守常量池的有关规定。

根据《Java 虚拟机规范》中第4.4 章节常量池的定义,CONSTANT_String_info用于表示java.lang.String 类型的常量对象,格式如下:
在这里插入图片描述
其中,string_index 项的值必须是对常量池的有效索引, 常量池在该索引处的项必须是CONSTANT_Utf8_info 结构,表示一组Unicode 码点序列,这组Unicode 码点序列最终会被初始化为一个String 对象。
在这里插入图片描述
其中,length 则指明了bytes[]数组的长度,其类型为u2,u2 表示两个字节的无符号数,那么1 个字节有8位,2 个字节就有16 位。16 位无符号数可表示的最大值位2^16 - 1 = 65535。也就是说,Class 文件中常量池的格式规定了,其字符串常量的长度不能超过65535。那么,我们尝试使用以下方式定义字符串:

        // 65535长度的AAA赋值
        String result = "AAAA...AAA";
        System.out.println(result);

尝试使用javac 编译,同样会得到"错误: 常量字符串过长",那么原因是什么呢?

其实,这个原因在javac 的代码中是可以找到的,在Gen 类中有如下代码:

    private void checkStringConstant(DiagnosticPosition var1, Object var2) {
        if (this.nerrs == 0 && var2 != null && var2 instanceof String && ((String) var2).length() >= 65535){
            this.log.error(var1, "limit.string", new Object[0]);
            ++this.nerrs;
        }
    }

代码中可以看出,当参数类型为String,并且长度大于等于65535 的时候,就会导致编译失败。

综上可以得出结论,当对String进行常量赋值,其最大长度为65534。而在运行时赋值,其最大长度为2^31 - 1。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值