环境: JDK8
声明:Java的字符串如果放在堆中,则没有长度限制;如果放在常量池中,则会有长度限制,规则如下(如直接定义的 String str = "xxx" 或 new String("xxx") 这两种会直接将字符串存于常量池,其他情况产生的字符串的值实际上都在堆中):
Java的字符串能表示的最大长度,是使用 UTF-8 缩略编码表示的最大 64kb 的长度。
关于 java 编译产生的 Class 文件中的字符串编码
Class文件使用的字符串编码是 UTF-8 缩略编码。UTF-8 缩略编码与普通 UTF-8 编码的区别是:
从 '\u0001' 到 '\u007f' 之间的字符(相当于 1~127 的ASCII码)的缩略编码使用一个字节表示,从 '\u0080' 到 '\u07ff' 之间的所有字符的缩略编码用两个字节表示,从 '\u0800' 开始到 '\uffff' 之间的所有字符的缩略编码就按照普通 UTF-8 编码规则使用三个字节表示。
顺便提一下,由于 Class 文件中方法、字段等都需要引用 CONSTANT_Utf8_info 型常量来描述名称,所以 CONSTANT_Utf8_info 型常量的最大长度也就是 Java 中方法、字段名的最大长度。而这里的最大长度就是 length 的最大值,既 u2 类型能表达的最大值 65536。所以 Java 程序中如果定义了超过 64kb 英文字符的变量或方法名,即使规则和全部字符都是合法的,也会无法编译。
内容完。
对以上出现关键词的解释:
1、CONSTANT_Utf8_info常量的表结构如下:
类型 | 名称 | 数量 |
u1 | tag | 1 |
u2 | length | 1 |
u1 | bytes | length |
tag 是标志位,它用于区分常量类型;length值说明了这个 UTF-8 编码的字符串长度是多少字节,它后面紧跟着的长度为 length 字节的连续数据是一个使用 UTF-8 缩略编码表示的字符串。
2、u1 和 u2 的解释:
u1表示1个字节,u2表示两个字节。
以上内容来自《深入理解Java虚拟机》:JVM高级特性与最佳实践(第三版) 周志明著,6.3.2 节 常量池
实战:
编写 new String("xxx") 或 String str = "xxx" 时,如果字符串长度超过64kb则会拒绝编译
转载请在明显位置附上原文链接。