Java中的字符串的最大长度

Wesley13
• 阅读 841

Java中的字符串的最大长度

看String的源码可以看出来,String实际存储数据的是char value[],数组的长度是int类型,

整数在java中是有限制的,我们通过源码来看看int类型对应的包装类Integer可以看到,其长度最大限制为2^31 -1,那么说明了数组的长度是0~2^31-1,那么计算一下就是(2^31-1 = 2147483647 = 4GB)。但我们开发的时候,也会出现因为字符串过长导致的编译错误:常量字符串过长。这是为什么呢?

对于字符串可以承受的最大长度,要分为2个阶段,一个是编译时期(也就是你代码定义了一个String字符串,String s= "xiaohu"),一个是运行时期(指在程序运行过程中)。

当String为常量时

这时候,JDK编译期是对String字符串存在限制的,我们都知道JVM里面是包含常量池的,(是一种对字符串的性能优化,不用反复创建新的字符串了)当我们使用字符串字面量直接定义String的时候,是会把字符串在常量池中存储一份的。常量池中的每一项常量都是一个表,都有自己对应的类型。Java中的UTF-8编码的Unicode字符串在常量池中以CONSTANT_Utf8_info类型表,结构如下:

Java中的字符串的最大长度

u2类型的length的值就表明了这个UTF-8编码字符串长度是多少字节。

所以CONSTANT_Utf8_info型常量对应的最大长度也就是java中UTF-8编码的字符串的长度,顺便提一下Class文件中的方法和字段也是引用CONSTANT_Utf8_info型常量来描述名称的。u2是无符号的16位整数,因此理论上允许的的最大长度是2^16-1=65535。

总结一下:在Javac编译器下,字符串String的最大长度限制也即是U2类型所能表达的最大长度65534。避开javac最大长度是65535?

当String为变量时

String内部是以char数组的形式存储,数组的长度是int类型,那么String允许的最大长度就是Integer.MAX_VALUE了。又由于java中的字符是以16位存储的,因此大概需要4GB的内存才能存储最大长度的字符串。

总结

首先字符串的内容是由一个字符数组 char[] 来存储的,由于数组的长度及索引是整数,且String类中返回字符串长度的方法length() 的返回值也是int ,所以通过查看java源码中的类Integer我们可以看到Integer的最大范围是2^31 -1,由于数组是从0开始的,所以数组的最大长度可以使【0~2^31】通过计算是大概4GB。

但是通过翻阅java虚拟机手册对class文件格式的定义以及常量池中对String类型的结构体定义我们可以知道对于索引定义了u2,就是无符号占2个字节,2个字节可以表示的最大范围是2^16 -1 = 65535。

其实是65535,但是由于JVM需要1个字节表示结束指令,所以这个范围就为65534了。超出这个范围在编译时期是会报错的,但是运行时拼接或者赋值的话范围是在整形的最大范围。

Eclise编译超过65534长度的字符串不报错,是Eclipse有自己的Java编译器。JDT优化为了StringBuilder的append。

Eclise使用自己的编译器。主要原因是JDT核心具有渐进式编译的能力,这意味着它会逐步编译代码中的更改(这也是Eclipse不需要编译按钮的原因,因为它会在检测到更改时自动编译)。但Oracle的JDK不支持增量编译。

本文分享自微信公众号 - 聊聊电商业务与技术(talkecom)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java基础
JAVA集合在处理数据的过程中经常会需要一个容器来存储某一类型的数据,Java中的数组就是这样一种容器。但Java中的数组有其局限性,定义后的数组长度不可变,超出数组长度后就不能再存放数据了。而很多时候我们并不知道数据到底有多少,所以就需要有不定长的容器来存放数据,这就是集合,Java中的集合都采用了泛型实现,可以存入任何类型的对象数据
Stella981 Stella981
3年前
HIVE string与varchar调研文档
一、简要介绍:Hive有2种类型用于存储变长文本。1.Hive0.12.0版本引入了VARCHAR类型,VARCHAR类型使用长度指示器(1到65355)创建,长度指示器定义了在字符串中允许的最大字符数量。如果一个字符串值转换为或者被赋予一个varchar值,其长度超过了长度指示器则该字符串值会自动被截断。2.STRING存储变长的文本,对长度
Wesley13 Wesley13
3年前
Java 集合类
为什么使用集合数组长度是固定,如果要改变数组的长度需要创建新的数组将旧数组里面的元素拷贝过去,使用起来不方便。java给开发者提供了一些集合类,能够存储任意长度的对象,长度可以随着元素的增加而增加,随着元素的减少而减少,使用起来方便一些。数组和集合的区别区别1:数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类
Wesley13 Wesley13
3年前
Java如何遍历二维数据
/\需求:二维数组遍历外循环控制的是二维数组的长度,其实就是一维数组的个数。内循环控制的是一维数组的长度。\/classArray2Test{publicstaticvoidmain(String\\args){//定义一个二维数组int\\\\arr{{1,2,3}
Wesley13 Wesley13
3年前
MySQL索引的索引长度问题
MySQL的每个单表中所创建的索引长度是有限制的,且对不同存储引擎下的表有不同的限制。在MyISAM表中,创建组合索引时,创建的索引长度不能超过1000,注意这里索引的长度的计算是根据表字段设定的长度来标量的,例如:createtabletest(idint,name1varchar(300),name2varchar(300),nam
Stella981 Stella981
3年前
LeetCode 5561. 获取生成数组中的最大值
文章目录1\.题目2\.解题1\.题目给你一个整数n。按下述规则生成一个长度为n1的数组nums:nums00nums11当2<2i<n时,nums2inumsi
Stella981 Stella981
3年前
JavaScript常用函数
1\.字符串长度截取functioncutstr(str,len){vartemp,icount0,patrn/^\x00\xff/,strre"";for(vari
Wesley13 Wesley13
3年前
Java集合笔记
1.1集合概述在前面基础班我们已经学习过并使用过集合ArrayList<E,那么集合到底是什么呢?集合:集合是java中提供的一种容器,可以用来存储多个数据。集合和数组既然都是容器,它们有啥区别呢?数组的长度是固定的。集合的长度是可变的。数组中存储的是同一类型的元素,可以存储基本数据类