在Java中的string的最大长度 – 调用length()方法

我的问题是非常基本的,但是我没有在Googlesearch上find答案。

Java中 ,指向length()方法调用的String对象可能具有的最大大小是多less?

我知道length()返回一个String的大小为char [] ;

考虑到String类的length方法返回一个int ,那么该方法返回的最大长度将是Integer.MAX_VALUE ,即2^31 - 1 (或大约20亿)。

就数组的长度和索引而言(比如char[] ,这可能是为String实现内部数据表示的方式), 第10章: Java SE 7中的 数组说明如下:

包含在数组中的variables没有名字; 相反,它们是由使用非负整数索引值的数组访问expression式引用的。 这些variables被称为数组的组件 。 如果一个数组有n分量,我们说n是数组的长度 ; 数组的元素使用从0n - 1整数索引进行引用。

而且,索引必须是int值,如10.4节所述 :

数组必须用int值进行索引;

因此,看起来这个极限确实是2^31 - 1 ,因为这是一个非负的int值的最大值。

但是,可能会有其他限制,例如数组的最大可分配大小。

由于数组必须使用整数进行索引,因此数组的最大长度为Integer.MAX_INT (2 31 -1或2 147 483 647)。 这是假设你有足够的内存来保存这个大小的数组,当然。

java.io.DataInput.readUTF()java.io.DataOutput.writeUTF(String)声明一个String对象由两个字节的长度信息和string中每个字符的修改的UTF-8表示forms表示。 由此得出结论,当与DataInputDataOutput一起使用时,String的长度受string修改的UTF-8表示字节数的限制。

另外,Java虚拟机规范中的CONSTANT_Utf8_info规范定义了如下结构。

 CONSTANT_Utf8_info { u1 tag; u2 length; u1 bytes[length]; } 

你可以发现'长度'的大小是两个字节

某个方法(例如String.length() )的返回types是int并不总是意味着它允许的最大值是Integer.MAX_VALUE 。 相反,在大多数情况下, int只是出于性能原因而select的。 Java语言规范说,在计算之前(如果我的内存正确地为我服务),那些小于int被转换为int ,并且这是在没有特殊原因时selectint一个原因。

编译时的最大长度至多为65536.再次注意,长度是修改的UTF-8表示的字节数,而不是String对象中的字符数。

String对象在运行时可能有更多的字符。 但是,如果要使用带有DataInputDataOutput接口的String对象,最好避免使用太长的String对象。 当我实现了DataInput.readUTF()DataOutput.writeUTF(String) Objective-C等价物时,我发现了这个限制。

显然它绑定到一个int,它是0x7FFFFFFF(2147483647)。

String类的length()方法的返回types是int

public int length()

请参阅http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#length();

所以int的最大值是2147483647

string在内部被视为char数组,因此索引是在最大范围内完成的。 这意味着我们不能索引第2147483648个成员。所以在java中String的最大长度是2147483647。

原始数据typesint在java.As中为4个字节(32位)。1位(MSB)用作符号位 。范围限制在-2 ^ 31到2 ^ 31-1 (-2147483648到2147483647)之间。 我们不能使用负值进行索引。显然,我们可以使用的范围是从0到2147483647。

我有一台带有8GB内存的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()); 

这打印:

 Requested array size exceeds VM limit 1207959550 

所以,最大arrays大小似乎是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); } } 

打印:

 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 

所以,最大似乎是Integer.MAX_VALUE – 2,或(2 ^ 31) – 3

PS我不知道为什么我的StringBuilder超出了1207959550而我的char[]超出(2 ^ 31)-3。 AbstractStringBuilder似乎将内部char[]的大小扩大了两倍,所以可能会导致问题。