关于String到底有没有长度限制,相信在实际开发中,很多开发者都遇到过处理超长字符串的问题。下面我们就来结合Java原理来分析关于String类型长度限制。
String类型的长度
笔者就遇到这样一个问题,将一个超大的字符串使用String类型进行处理,然后点运行程序之后,就会报错。这到底是为什么呢?
在String类型中,有一个如下的构造函数。
public String(byte bytes[], int offset, int length)
这个构造函数中,传入了一个字符串的长度,并且数据类型是int类型,也就是说传入的字符串长度最大支持的长度应该是int的表数范围。也就是2的31次方减一。是不是String类型的长度真的就是这个长度呢?在笔者操作数据的时候,数据长度明显要比这个长度要小,但是还是报错了?也就是说笔者在编译的时候就报错了。
也就是说这里的长度只是支持的理论值,也就是在运行的时候支持的大小,但是在实际编译的时候字符串的长度是有限制的。
String s = "11111...1111";//其中有10万个字符"1"
这个时候会有人问?既然支持的构造方法长度达到2147483647(2^31 - 1)长度了,那么为什么不能编译呢?
常量池的限制
在介绍JVM的时候,我们知道Java程序执行首先要通过编译操作生成一个class文件,但是在这个Class文件生成过程中会遵守一些规则,这个规则被称为是虚拟机规范。那么在虚拟机规范中就对String类型的长度进行了规定。
而所谓的规定就是String类型作为字符串所能表示的大小范围,我们知道,在世界上有很多的字符集,并且这些字符都有自己的字符集编码例如UTF-8、GBK、Unicode等等。而在Java底层所支持的就是Unicode编码,这种编码最终就被转换成一个String字符串。而在这个操作过程中,需要遵循的就是Unicode编码规范大小,也就是65535个长度。
也就是说在Class文件中对于常量池的规定就是不能超过65535。
那么我们将上面的测试代码改成
String s = "11111...1111";//65535字符"1"
这个时候还是会报错。这个是什么原因呢?
这个是因为,在我们操作字符串编译常量池的时候,大于或者等于65535的时候都会报错。这个现象,大家可以通过Debug操作来追踪相关的内容。
运行时限制
在上面我们提到了在编译阶段的限制,并且介绍了理论运行阶段的值限制,那么在运行阶段String的长度有什么限制呢?
在上面我们介绍了最大的长度应该是4G,也就是是Integer的表数范围,如果当一个字符串超过这个大小的时候也会报错。
这个时候有人就会疑惑为什么在编译的时候是65535而运行的时候就可以超过这个限制呢?
其实这个是很常见的的,在编译的时候有很多的规则检查,但是通过了这些规则检查之后,在运行阶段就需要更多的内存支持,例如将一个图片转换成BASE64字符进行存储,在编译的时候我们只需要定义一个变量准备接受这个字符串就行了,在实际使用的时候才能知道这个字符串里面到底能够存储多少字符。
总结
从上面的分析可以知道,字符串的大小是有限制的,在编译阶段遵守的是虚拟机规范,而在运行阶段则是不能超过Int的表数范围。
本文暂时没有评论,来添加一个吧(●'◡'●)