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。

Java中String字符串长度相关推荐

  1. Java中String字符串:空字符串、存放空的字符串、null的区别

    Java中String字符串:空字符串.存放空的字符串.null的区别 Java String字符串中有三种特殊的字符串:空字符串.存放空的字符串.字符串为Null,如下所示: String str1 ...

  2. Java中String字符串截取几种方法(substring,split)

    Java中String字符串截取几种方法 substring,split 这是一个Java中的String的基础用法的演示. 下面通过代码对大家进行讲解 substring 这里用来ndexOf,la ...

  3. Java中String 字符串与List<String>互转

    Java中String 字符串与List互转 大家好,我是酷酷的韩~ 1.String转List public static void main(String[] args) {String aa = ...

  4. Java中string字符串的值_Java中的字符串(String)

    一.基本概念: 字符串是一系列字符串的序列.在Java语言中字符串是用一对对双引号"",括起来的字符系列.例如"Hello","你好".从数 ...

  5. Java中string字符串和char字符之间的千丝万缕

    目录 前言 String字符串和char字符的区别 拓展 相互转换 String字符串转换成char字符数组 char字符转换成String字符串 char字符数组转换成String字符串 Strin ...

  6. Java中String字符串toString()、String.valueOf()、String强转、+ 的区别

    Object#toString(): Object object = getObject(); System.out.println(object.toString()); 在这种使用方法中,因为ja ...

  7. JAVA中String字符串比较equals()和equalsIgnoreCase()的区别

    标签: equals和equalsIgnoreC 2012-11-11 16:03 65644人阅读 评论(0) 收藏 举报  分类: JAVA(3)  1.使用equals( )方法比较两个字符串是 ...

  8. java中String字符串的替换函数:replace与replaceAll的区别

    例如有如下x的字符串 String x = "[kllkklk\\kk\\kllkk]"; 要将里面的"kk"替换为++,可以使用两种方法得到相同的结果 rep ...

  9. JAVA中String字符串删除指定字符的办法

    场景: 有个字符串oldStr,内容为"a,b,c,d,e",想动态删除某个字符,或c或b. 解决办法: 1.转数组 String[] arr = oldStr.split(&qu ...

  10. Java 中 String 字符串可以有多长?65535?

最新文章

  1. android垂直公告,【Android之垂直翻页公告】
  2. 2010年暑假送给大学生30句话
  3. Mysql学习总结(4)——MySql基础知识、存储引擎与常用数据类型
  4. Linux最小体积mysql安装_Linux下安装MySQL以及一些小坑
  5. 4米乘以12米CAD图_SolidWorks转CAD时让字体格式相对完好的方法
  6. 安装Pywin32后无法正常引用pyd文件
  7. 耗时6年的DK博物科普巨著,全面提升孩子的认知高度
  8. 95-134-110-源码-维表-Flink 1.9.0 维表实现
  9. 从h264码流中获取图像的宽高---版本2(简洁版)
  10. firefox无法打开php,php – CORS无法在Firefox中运行
  11. 修改GDAL库支持RPC像方改正模型
  12. js时间格式化 YYYY/MM/DD HH:MM:SSS
  13. Centos7-安装Weblogic并配置 domain
  14. DPDK 框架原理简介(0001转)
  15. iOS 报错 : dyld: Library not loaded: @rpath/
  16. 使用ppo强化学习算法预测双色球彩票程序
  17. ubuntu20.04安装搜狗输入法
  18. 芯鼎盛LED恒流驱动芯片TX6128设计的DC-DC开关电源降压恒流DEMO说明
  19. 江南春新年围炉夜谈:如何破解增长焦虑?
  20. 一个小白程序员的目标

热门文章

  1. 星星之火-57:前传接口 CPRI的速率、能力、小区带宽之间的映射关系
  2. 数学对数 log lg ln 简介
  3. backfire openwrt安装click modular router
  4. cors js解决js跨域问题
  5. mysql导入GP_GP数据库gpload数据导入详细操作
  6. android自动点击开红包,自动点击连点器
  7. linux下这输入法切换大小写,Life With Arch:让Capslock成为输入法切换快捷键
  8. digester java_JAVA Digester 简介
  9. java rgb565转rgb888_RGB565 转RGB888的循环补偿(zz)
  10. Matlab实现Sandbox方法计算分形维数