String的Java中的最大长度 - 调用length()方法

tai*_*chi 138 java string

Java中,String对象可能具有的最大大小是什么,引用length()方法调用?

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

coo*_*ird 156

考虑到String类' length方法返回一个int,该方法将返回的最大长度Integer.MAX_VALUE2^31 - 1(或大约20亿).

在长度和数组的索引,(如而言char[],这可能是内部数据表示为实现方式StringS),第10章:数组Java语言规范,Java SE 7中版说以下内容:

数组中包含的变量没有名称; 相反,它们由使用非负整数索引值的数组访问表达式引用.这些变量称为数组的 组件.如果一个数组有n组件,我们说n是数组的 长度 ; 阵列的组件是使用整数索引从参考0n - 1,包括端值.

此外,索引必须是int值,如第10.4节所述:

数组必须按int值索引;

因此,似乎确实存在限制2^31 - 1,因为这是非负值的int最大值.

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

  • 实际上,Integer.MAX_VALUE是2 ^ 31-1.:) (25认同)
  • 我只是尝试在一个长度超过65546的hello world java程序中定义一个字符串文字.`javac`给出了一个关于该文字太长的错误:`javac HelloWorld.java 2>&1 | head -c 80 HelloWorld.java:3 :常量字符串太长了 (4认同)
  • @dlamblin:这听起来像'javac`对`String`*literals*(不是`String`对象)的限制,因为我在Java语言规范和JVM规范中找不到对`String`文字的大小限制的任何引用.我尝试制作一个大于100,000个字符的`String`文字,并且Eclipse编译器没有编译它的问题.(并且运行该程序能够显示该文字的`String.length`大于100,000.) (2认同)
  • @Premraj这是三年前所以我不得不考虑一下.;)我的意思是; 要构建一个最大大小的字符串,你需要很多内存,可能比你还要多.你需要每个字符两个字节~4GB,但你需要从StringBuilder或char []构建它,这意味着你需要每个字符另外两个字节来创建它,即另一个~4 GB(至少暂时) (2认同)

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对象可能在运行时可以拥有更多字符.但是,如果要使用StringDataInputDataOutput接口的对象,最好避免使用太长的String对象.当我实现Objective-C等价的DataInput.readUTF()和时,我发现了这个限制DataOutput.writeUTF(String).


Mic*_*ers 18

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


Fra*_*cis 5

显然它绑定到一个int,即0x7FFFFFFF(2147483647).


小智 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。


dan*_*ton 5

我有一台具有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 1207959550char[]达到极限。似乎将AbstractStringBuilder其内部的大小加倍以char[]使其增长,所以可能导致了问题。

  • 对这个问题的非常有用的实际处理 (2认同)