String长度限制?
作者:互联网
String我们在开发和学习中会经常用到,但对String类型的取值范围我们并不明确。
String底层是char数组,并未标明长度限制。java中可以对数组指定长度,如果不指定就以实际元素来指定
private final char value[];
从底层方法length()可以看出,返回的是int类型。
public int length()
而在java中,int的最大值是2^31-1 = 2147483647,也是value[]
数组的长度为 2^31-1 。
但当在程序中定义一个10万字符的字符串后编译,jvm会提示报错:java: 常量字符串过长
是因为jvm编译规范做了限制,在编译时,jvm会把字面量的字符串放到常量池中,而JVM中class文件做了规范。
所有在常量池的项都具有以下格式。
cp_info{
u1 tag;
u2 info[];
}
其中
u1 tag
表示标志符,代表当前这个常量属于什么类型;u2 info[]
由 tag 决定该数组的内容。(详见《Java虚拟机规范》 4.4章节)注:在class文件中,有专用的数据类型用于表示Class文件的内容,包括u1、u2、u4,分别代表1、2、4个字节无符号数;每个Class文件都由8个字节为单位的字节流组成,所有16 、 23 、 64 位长度的数据将被构造成2个 、 4个 、 8个 8字节单位来表示(详见《Java虚拟机规范》第4章)
tag对应的项有。
常量类型 | 值 |
---|---|
CONSTANT_Class | 7 |
CONSTANT_Fieldref | 9 |
CONSTANT_Methodref | 10 |
CONSTANT_InterfaceMethodref | 11 |
CONSTANT_String | 8 |
CONSTANT_Integer | 3 |
CONSTANT_Float | 4 |
CONSTANT_Long | 5 |
CONSTANT_Double | 6 |
CONSTANT_NameAndType | 12 |
CONSTANT_Utf8 | 1 |
CONSTANT_MethodHandle | 15 |
CONSTANT_MethodType | 16 |
CONSTANT_InvokeDynamic | 18 |
String对应的是CONSTANT_String项,具体定义格式为
CONSTANT_String_info{
u1 tag;
u2 string_index;
}
u1 tag
的值为CONSTANT_String(8);u2 string_index
的值必须是对常量池表的有效索引,且该索引处的项必须是CONSTANT_Utf8_info结构
字符串是以CONSTANT_Utf8型式在常量池中表示。class文件中CONSTANT_Utf8的具体定义格式,
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
u1 tag
的值为CONSTANT_Utf8(1);CONSTANT_Utf8_info的内容以u2 length
属性来确定长度;u1 bytes[length]
表示字符串值的byte数组
其中u2代表2个无符号占字节单位,而1 个字节占8位(bit),2个也就是16位,16位最高表示的是2^16 - 1 = 65535,又因为虚拟机需要1个字节作为结束指令,所以其真正的有效范围是【0-65564】。当然这个范围是编译期的有效范围,而运行时拼接的字符串是在整形的最大范围。
当然,如果使用的字符是中文字符,那么这个长度还会再减少,因为UTF8编码中大部分中文占3个字节,而21845个正好占用65535个字节。所以编译期的有效范围还需结合实际使用的字符来决定
标签:限制,CONSTANT,String,u1,u2,tag,长度,字节 来源: https://www.cnblogs.com/hello12153-java/p/16449643.html