其他分享
首页 > 其他分享> > String长度限制?

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