;)

ал в статьях и книгах, что использованиеString s = new String("..."); следует избегать в значительной степени все время. Я понимаю, почему это так, но есть ли смысл вообще использовать конструктор String (String)? Я не думаю, что есть, и не вижу никаких доказательств в противном случае, но мне интересно, знает ли кто-либо в сообществе SO об использовании.

Точная копия: Какова цель выражения новой строки в Java?

Ответы на вопрос(6)

Ответ Дугласа* Я могу привести пример того, где я его использовал. Вы можете прочитать файл словаря с тысячами строк, каждая из которых представляет собой одно слово. Самый простой способ прочитать это использоватьBufferedReader.readLine().

К несчастью,readLine() выделяет буфер из 80 символов по умолчанию в качестве ожидаемой длины строки. Это означает, что обычно это позволяет избежать бессмысленного копирования - и немного потерянной памяти обычно не так уж плохо. Однако, если вы загружаете словарь коротких слов в течение всего времени работы приложения, вы в конечном итоге теряете много памяти. Мое "маленькое приложение" высосало намного больше памяти, чем следовало бы.

Решение было изменить это:

String word = reader.readLine();

в это:

String word = new String(reader.readLine());

... с комментарием, конечно!

* Я не могу вспомнить, работал ли я с Дугласом, когда это действительно произошло, или это просто совпадение, что он ответил на этот конкретный вопрос.

Решение Вопроса

Строковый конструктор, который считается бесполезным, оказывается полезным!

Оказывается, этот конструктор может быть полезен, по крайней мере, в одном случае. Если вы когда-либо заглядывали в исходный код String, вы видели, что он имеет не только поля для значения массива char и количества символов, но также для смещения в начале String. Это сделано для того, чтобы Strings могли совместно использовать значение массива char с другими Strings, как правило, в результате вызова одного из методов substring (). Java была классно отчитана за это в jwz 'rant' из лет назад:

Единственная причина таких издержек состоит в том, что String.substring () может возвращать строки, которые используют один и тот же массив значений. Делать это за счет добавления 8 байтов к каждому объекту String - это не чистая экономия ...

Помимо экономии байтов, если у вас есть такой код:

// imagine a multi-megabyte string here  
String s = "0123456789012345678901234567890123456789";  
String s2 = s.substring(0, 1);  
s = null;

Теперь у вас будет строка String s2, которая, хотя и выглядит как односимвольная строка, содержит ссылку на гигантский массив char, созданный в строке String s. Это означает, что массив не будет собирать мусор, даже если мы явно исключили String s!

Исправление для этого заключается в использовании нашего ранее упомянутого «бесполезного» конструктора String, например:

String s2 = new String(s.substring(0, 1));  

Не известно, что этот конструктор фактически копирует это старое содержимое в новый массив, если старый массив больше, чем количество символов в строке. Это означает, что старое содержимое String будет собираться как задумано. Счастлив, рад, радость, радость.

В заключение,Кэт Марсен делает эти пункты,

Прежде всего, строковые константы никогда не собираются мусором. Во-вторых, строковые константы являются внутренними, что означает, что они являются общими для всей виртуальной машины. Это экономит память. Но это не всегда то, что вы хотите.

Конструктор копирования в String позволяет вам создать частный экземпляр String из литерала String. Это может быть очень полезно для создания значимых объектов мьютекса (для целей синхронизации).

 Jesper24 мар. 2015 г., 12:48
Обратите внимание, что это больше не актуально, поскольку Java 7 (я думаю), где реализацияString.substring() был изменен, чтобы избежать этой проблемы.

изJavadoc

/**
 * Initializes a newly created {@code String} object so that it represents
 * the same sequence of characters as the argument; in other words, the
 * newly created string is a copy of the argument string. Unless an
 * explicit copy of {@code original} is needed, use of this constructor is
 * unnecessary since Strings are immutable.
 *
 * @param  original
 *         A {@code String}
 */
public String(String original){.....}

единственный «полезный» случай - это когда исходная строка является частью гораздо большего резервного массива. (например, созданный как подстрока). Если вы хотите хранить только небольшую подстроку и собирать мусор в большом буфере, возможно, имеет смысл создать новую строку.

 Jon Skeet21 янв. 2009 г., 16:20
И в любом случае вы не всегда контролируете, что создает строку - посмотрите мой ответ для примера из реальной жизни.
 Tom Hawtin - tackline21 янв. 2009 г., 16:23
Лучшие (IMHO) реализации String сбрасывают смещение и длину. Тем не менее, вам, вероятно, придется иметь дело с не очень хорошими реализациями.
 Michael Myers♦21 янв. 2009 г., 16:17
Нет, подстрока сохраняет указатель на исходный символ [] вместо создания нового (в этом случае это быстрее, но может привести к утечке памяти).
 Paul Tomblin21 янв. 2009 г., 16:02
Разве подстрока или что-то, что вы использовали для ее вырезания, уже не создали новую строку?

копия оригинальной строки, если вы не хотите, чтобы дать ссылку на исходную строку. Но так как строки неизменяемы, я не вижу варианта использования дляэто ;)

щих целей. Конструктор String с аргументом String используется редко, кроме как для создания независимой копии существующей строковой переменной. В основном используйте его, чтобы «уточнить» ваш код. Не меньше.

Ваш ответ на вопрос