Java 字符串 UTF-8 限制
Java String UTF-8 limits
我正在尝试直接从文件中反序列化字符串,我对超长字符串有疑问:Java 字符串的字符数限制等于 Integer.MAX_VALUE
,即 31^2- 1.
但是我的问题来了:当我有一个 UTF-8 字符串,其大小略小于该大小但由大小超过 1 个字节的字符组成时会发生什么,然后我要求 Java 给我字节数组?
为了更清楚,如果我可以 运行 这段代码会怎样? (我没有足够的 RAM):
String toPrint = "";
String string100 = "";
int max = Integer.MAX_VALUE -100;
for (int i = 0; i < 100; i += 10) {
string100 += "1234567ñ90";
}
for (int i = 0; i < max; i += 100) {
toPrint += string100;
}
System.out.println("String complete!");
byte[] byteArray = toPrint.getBytes(StandardCharsets.UTF_8);
System.out.println(byteArray.length);
System.exit(0);
是否打印 "String complete!"?还是之前坏过?
数组大小也被限制为Integer.MAX_VALUE
(这也是String
大小被限制的原因,毕竟有char[]
做后盾),所以无法得到字节数组如果编码使用的字节多于此,则无论 String
的字符大小是多少。
最终结果将是 OutOfMemoryError
,但首先创建 String
会成功。
从根本上说,Strings
的限制是其中的 char
数组不能超过最大数组长度,这大约是 Integer.MAX_VALUE
并且大于您的变量 max
。字符串将其字符存储在 UTF-16 中,因此字符串的 UTF-16 表示不能超过最大数组长度。 UTF-8 中的字节数和逻辑字符数(Unicode 代码点,或 UTF-32 字符)最终无关紧要。
现在让我们转到您的特定示例。由于“1234567ñ90”中的 10 个字符中的每一个都是单个 UTF-16 值,因此该字符串占用 String
的 char
数组的 10 个值。尽管您的代码性能糟糕且内存要求高,但如果有足够的可用内存,它最终应该达到 "String complete!"。但是,当转换为 UTF-8 时它会中断,因为字符串的 UTF-8 表示比最大数组长度长,因为“ñ”需要超过一个字节。
我正在尝试直接从文件中反序列化字符串,我对超长字符串有疑问:Java 字符串的字符数限制等于 Integer.MAX_VALUE
,即 31^2- 1.
但是我的问题来了:当我有一个 UTF-8 字符串,其大小略小于该大小但由大小超过 1 个字节的字符组成时会发生什么,然后我要求 Java 给我字节数组?
为了更清楚,如果我可以 运行 这段代码会怎样? (我没有足够的 RAM):
String toPrint = "";
String string100 = "";
int max = Integer.MAX_VALUE -100;
for (int i = 0; i < 100; i += 10) {
string100 += "1234567ñ90";
}
for (int i = 0; i < max; i += 100) {
toPrint += string100;
}
System.out.println("String complete!");
byte[] byteArray = toPrint.getBytes(StandardCharsets.UTF_8);
System.out.println(byteArray.length);
System.exit(0);
是否打印 "String complete!"?还是之前坏过?
数组大小也被限制为Integer.MAX_VALUE
(这也是String
大小被限制的原因,毕竟有char[]
做后盾),所以无法得到字节数组如果编码使用的字节多于此,则无论 String
的字符大小是多少。
最终结果将是 OutOfMemoryError
,但首先创建 String
会成功。
从根本上说,Strings
的限制是其中的 char
数组不能超过最大数组长度,这大约是 Integer.MAX_VALUE
并且大于您的变量 max
。字符串将其字符存储在 UTF-16 中,因此字符串的 UTF-16 表示不能超过最大数组长度。 UTF-8 中的字节数和逻辑字符数(Unicode 代码点,或 UTF-32 字符)最终无关紧要。
现在让我们转到您的特定示例。由于“1234567ñ90”中的 10 个字符中的每一个都是单个 UTF-16 值,因此该字符串占用 String
的 char
数组的 10 个值。尽管您的代码性能糟糕且内存要求高,但如果有足够的可用内存,它最终应该达到 "String complete!"。但是,当转换为 UTF-8 时它会中断,因为字符串的 UTF-8 表示比最大数组长度长,因为“ñ”需要超过一个字节。