在Java中,String对象可能具有的最大大小是什么,引用length()方法调用?
我知道length()返回的大小String为a char [];
coo*_*ird 156
考虑到String类' length方法返回一个int,该方法将返回的最大长度Integer.MAX_VALUE是2^31 - 1(或大约20亿).
在长度和数组的索引,(如而言char[],这可能是内部数据表示为实现方式StringS),第10章:数组的Java语言规范,Java SE 7中版说以下内容:
数组中包含的变量没有名称; 相反,它们由使用非负整数索引值的数组访问表达式引用.这些变量称为数组的 组件.如果一个数组有
n组件,我们说n是数组的 长度 ; 阵列的组件是使用整数索引从参考0到n - 1,包括端值.
此外,索引必须是int值,如第10.4节所述:
数组必须按
int值索引;
因此,似乎确实存在限制2^31 - 1,因为这是非负值的int最大值.
但是,可能会有其他限制,例如数组的最大可分配大小.
Tak*_*aki 21
java.io.DataInput.readUTF()并且java.io.DataOutput.writeUTF(String)说一个String对象由两个字节的长度信息和字符串中每个字符的修改的UTF-8表示来表示.这得出结论,String的长度受到与DataInput和一起使用时字符串的修改后的UTF-8表示的字节数的限制DataOutput.
此外,所述的说明书CONSTANT_Utf8_info在Java虚拟机规范定义发现如下的结构.
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
Run Code Online (Sandbox Code Playgroud)
您可以发现'length'的大小是两个字节.
某种方法(例如String.length())的返回类型int并不总是意味着其允许的最大值是Integer.MAX_VALUE.相反,在大多数情况下,int仅出于性能原因选择.Java语言规范说大小小于整数的整数在计算之前int被转换为int(如果我的记忆正确地为我服务),并且int在没有特殊原因时选择它是一个理由.
编译时的最大长度最多为65536.再次注意,长度是修改后的UTF-8表示的字节数,而不是String对象中的字符数.
String对象可能在运行时可以拥有更多字符.但是,如果要使用String带DataInput和DataOutput接口的对象,最好避免使用太长的String对象.当我实现Objective-C等价的DataInput.readUTF()和时,我发现了这个限制DataOutput.writeUTF(String).
小智 5
String 类的 length() 方法的返回类型是int。
公共整数长度()
参考http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#length()
所以 int 的最大值是2147483647。
String在内部被认为是char数组,所以索引是在最大范围内完成的。这意味着我们不能索引第 2147483648 个成员。所以 java 中 String 的最大长度是 2147483647。
java中的原始数据类型int是4个字节(32位)。由于1位(MSB)用作符号位,范围被限制在-2^31到2^31-1(-2147483648到2147483647)内。我们不能为索引使用负值。所以显然我们可以使用的范围是从 0 到 2147483647。
我有一台具有8GB RAM的2010 iMac,运行带有Java 1.8.0_25的Eclipse Neon.2版本(4.6.2)。使用VM参数-Xmx6g,我运行了以下代码:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
try {
sb.append('a');
} catch (Throwable e) {
System.out.println(i);
break;
}
}
System.out.println(sb.toString().length());
Run Code Online (Sandbox Code Playgroud)
打印:
Requested array size exceeds VM limit
1207959550
Run Code Online (Sandbox Code Playgroud)
因此,似乎最大数组大小为〜1,207,959,549。然后我意识到我们实际上并不关心Java是否会耗尽内存:我们只是在寻找最大的数组大小(这似乎是某个地方定义的常量)。所以:
for (int i = 0; i < 1_000; i++) {
try {
char[] array = new char[Integer.MAX_VALUE - i];
Arrays.fill(array, 'a');
String string = new String(array);
System.out.println(string.length());
} catch (Throwable e) {
System.out.println(e.getMessage());
System.out.println("Last: " + (Integer.MAX_VALUE - i));
System.out.println("Last: " + i);
}
}
Run Code Online (Sandbox Code Playgroud)
哪些打印:
Requested array size exceeds VM limit
Last: 2147483647
Last: 0
Requested array size exceeds VM limit
Last: 2147483646
Last: 1
Java heap space
Last: 2147483645
Last: 2
Run Code Online (Sandbox Code Playgroud)
因此,似乎最大值是Integer.MAX_VALUE-2或(2 ^ 31)-3
StringBuilder附言:我不确定为什么我在(2 ^ 31)-3 1207959550时char[]达到极限。似乎将AbstractStringBuilder其内部的大小加倍以char[]使其增长,所以可能导致了问题。
| 归档时间: |
|
| 查看次数: |
217193 次 |
| 最近记录: |