String长度的限制
在JVM编译中有规范要求。在开发中遇到的String长度限制的场景(将某固定文件转码成Base64的形式用字符串存储,在运行时需要的时候在转回来,当时文件比较大)。
String存储字符串,其实是使用的一个char类型的数组来存储字符串的字符的。
public final class String implements java.io.Serializable, Comparable<String> , CharSequence{
/** The value is used for character storage*/
private final char value[];
String的长度限制是有先提条件的,看String中返回length的方法
/**
*Return the length of this string
*The length is equal to the number of <a href="Character.html#unicode">
*code units</a> in the string
*@return the length of the sequence of characters represented by this object
*/
public int length(){
return value.length;
}
我们看到上面的代码返回值类型是int类型,java中定义数组是可以给数组指定长度的,不指定的话是根据数组元素来指定的:
int [] arr = new int[20];//定义一个长度为20的数组
int [] arr2 = {1,3,5,7,8,10};//则此时的数组长度为6
int类型在Java中是有限制的。通过源码分析int对应的包装类Integer,长度最大为0~2^31-1,那么就说明数组的长度就是 2^31-1, 2^31-1=2147483647=4GB
public final class Integer extends Number implements Comparable<Integer>{
/**
* A constant holding the minimum value an {@code int} can
* have, -2<sup>31</sup>-1
*/
@Native
public static final int MIN_VALUE = 0X80000000;
/**
* A constant holding the maximum value an {@code int} can
* have, 2<sup>31</sup>-1
*/
@Native
public static final int MAX_VALUE = 0X7fffffff;
但是定义一个10万个字符的字符串,编译之后虚拟机提示报错。但源码说的是21亿个。缩小的原因是JVM编译规范限制。在JVM编译时,如果我们将字符串定义成了字面量的形式,编译时JVM是会将其存放在常量池中,这时候JVM对这个常量池存储String类型就做了限制。
一个字节占8位,两个字节占16位。那么两个字节表示的范围就是2^16-1=65535。
但是需要注意的是,JVM需要1个字节表示结束指令65534.
字符串长度限制总结:
下面我们进行一下总结,字符串是有长度限制的。首先字符串的内容是由一个字符数组char[]来存储的,由于数组的长度及索引是int类型。且String类中返回字符串的方法length()的返回值也是int。
通过java源码中的类Integer我们可以看到Integer的最大范围是2^31-1
由于数组是从0开始的,所以数组的最大长度可以使【0~2^31】通过计算大概就是4GB。
通过翻阅java虚拟机手册,2个字节表示的最大范围是2^16-1=65535。
其实是65535,但是由于JVM需要1个字节表示结束指令,所以这个范围就是65534了。
超出这个范围在编译时期会报错,但是运行时拼接或者赋值的话范围是在整形的最大范围
资料来源:公众号 java面试那些事儿
其他
自己建立了一个技术群,大家愿意主动学习和分享,愿意一块实现一些有意思的技术,进行理论和实践的交流。这里面有前端和后段,不是单一的一种,方便大家沟通前后端兼容问题