Максимальная длина строки в Java - вызов метода length () - PullRequest
134 голосов
/ 03 мая 2009

В Java , какой максимальный размер может иметь String объект, ссылаясь на вызов метода length()?

Я знаю, что length() возвращает размер String как char [];

Ответы [ 6 ]

152 голосов
/ 03 мая 2009

Учитывая, что метод String class 'length возвращает int, максимальная длина, которая будет возвращена методом, будет Integer.MAX_VALUE , что составляет 2^31 - 1 (или приблизительно 2 млрд.)

С точки зрения длины и индексации массивов (например, char[], что, вероятно, является способом реализации внутреннего представления данных для String с), Глава 10. Массивы из Спецификация языка Java, Java SE 7 Edition гласит следующее:

Переменные, содержащиеся в массиве не иметь имен; вместо этого они ссылается на выражения доступа к массиву которые используют неотрицательный целочисленный индекс ценности. Эти переменные называются компоненты массива. Если массив n компонентов, мы говорим, n является длина массива; компоненты на массив ссылаются, используя целое число индексы от 0 до n - 1 включительно.

Кроме того, индексирование должно быть по int значениям, как указано в Раздел 10.4 :

Массивы должны индексироваться значениями int;

Таким образом, представляется, что предел действительно равен 2^31 - 1, поскольку это максимальное значение для неотрицательного значения int.

Однако, вероятно, будут другие ограничения, такие как максимальный выделяемый размер для массива.

20 голосов
/ 27 июля 2013

<a href="http://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#readUTF%28%29">java.io.DataInput.readUTF()</a> и <a href="http://docs.oracle.com/javase/7/docs/api/java/io/DataOutput.html#writeUTF%28java.lang.String%29">java.io.DataOutput.writeUTF(String)</a> говорят, что объект String представлен двумя байтами информации о длине и модифицированным представлением UTF-8 каждого символа в строке. Из этого следует, что длина строки ограничена количеством байтов измененного представления строки в кодировке UTF-8 при использовании с DataInput и DataOutput.

Кроме того, Спецификация CONSTANT_Utf8_info, найденная в спецификации виртуальной машины Java, определяет структуру следующим образом.

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

Вы можете найти, что размер '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).

18 голосов
/ 03 мая 2009

Поскольку массивы должны быть проиндексированы целыми числами, максимальная длина массива составляет Integer.MAX_INT (2 31 -1 или 2 147 483 647). Это, конечно, при условии, что у вас достаточно памяти для хранения массива такого размера.

5 голосов
/ 03 мая 2009

, очевидно, он связан с int, который равен 0x7FFFFFFF (2147483647).

4 голосов
/ 17 февраля 2017

У меня iMac 2010 года с 8 ГБ оперативной памяти, работающий под управлением Eclipse Neon.2 Release (4.6.2) с Java 1.8.0_25. С аргументом 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

Итак, максимальный размер массива составляет ~ 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

P.S. Я не уверен, почему мой StringBuilder увеличился до 1207959550, а мой char[] - до (2 ^ 31) -3. Кажется, что AbstractStringBuilder удваивает размер своего внутреннего char[], чтобы увеличить его, что, вероятно, вызывает проблему.

3 голосов
/ 18 декабря 2014

Возвращаемый тип метода length () класса String: int .

public int length ()

См. http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#length()

Таким образом, максимальное значение int равно 2147483647 .

Строка внутренне считается массивом символов, поэтому индексация выполняется в максимальном диапазоне. Это означает, что мы не можем индексировать 2147483648-й член. Так что максимальная длина строки в java равна 2147483647.

Примитивный тип данных int составляет 4 байта (32 бита) в java. Поскольку 1 бит (MSB) используется как знаковый бит , диапазон ограничен в пределах -2 ^ 31 до 2 ^ 31-1 (от -2147483648 до 2147483647). Мы не можем использовать отрицательные значения для индексации. Очевидно, что диапазон, который мы можем использовать, составляет от 0 до 2147483647.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...