Я читал в статьях и книгах, что использование String s = new String("...");
следует избегать почти все время. Я понимаю, почему это так, но есть ли смысл вообще использовать конструктор String (String)? Я не думаю, что есть, и не вижу никаких доказательств в противном случае, но мне интересно, знает ли кто-либо в сообществе SO об использовании.
Использование конструктора String (String) в Java
Ответ 1
Это хорошая статья: Конструктор String, который считается бесполезным, оказывается полезным в конце концов!
Оказывается, этот конструктор действительно может быть полезен, по крайней мере, в одном случае. Если вы когда-либо заглядывали в исходный код String, вы увидите, что у него есть не только поля для значения массива char и количество символов, но и смещение к началу строки. Это значит, что строки могут совместно использовать значение массива char с другими строками, как правило, это результат вызова одного из методов substring(). Java была известна за это в jwz 'Java 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. Это означает, что массив не будет собирать мусор, хотя мы явно вытеснили строку s!
Исправление для этого - использовать наш ранее упоминавшийся "бесполезный" конструктор String следующим образом:
String s2 = new String(s.substring(0, 1));
Не известно, что этот конструктор фактически копирует это старое содержимое в новый массив, если старый массив больше, чем количество символов в строке. Это означает, что старое содержимое String будет собираться мусором, как предполагалось. Счастливая радостная радость.
Наконец, Kat Marsen делает эти баллы,
Прежде всего, строковые константы никогда не собираются в мусор. Во-вторых, строковые константы являются intern'd, что означает, что они разделены по всей виртуальной машине. Это экономит память. Но это не всегда то, что вы хотите.
Конструктор копирования в String позволяет создать частный экземпляр String из строкового литерала. Это может быть очень полезно для создания значимых объектов мьютекса (для целей синхронизации).
Ответ 2
Если я правильно помню, единственным "полезным" случаем является то, что исходная строка является частью гораздо большего массива поддержки. (например, создается как подстрока). Если вы хотите, чтобы небольшая подстрока и мусор собирали большой буфер, может возникнуть смысл создать новую строку.
Ответ 3
Просто чтобы развернуть Douglas answer *, я могу привести пример того, где я его использовал. Подумайте о чтении словарного файла с тысячами строк, каждое из которых - всего лишь одно слово. Самый простой способ прочитать это - использовать BufferedReader.readLine()
.
К сожалению, readLine()
выделяет буфер по умолчанию 80 символов по умолчанию в качестве ожидаемой длины строки. Это означает, что обычно это может избежать бессмысленного копирования - и немного потерянной памяти обычно не так уж плохо. Однако, если вы загружаете словарь коротких слов в течение всего срока действия приложения, вы получаете огромное количество памяти, которая постоянно теряется. Мое "маленькое приложение" всасывало гораздо больше памяти, чем следовало делать.
Решение заключалось в том, чтобы изменить это:
String word = reader.readLine();
в это:
String word = new String(reader.readLine());
... с комментариями, конечно!
*
Я не помню, работал ли я с Дугласом, когда это произошло, или просто случайно, что он ответил на этот конкретный вопрос.
Ответ 4
Конструктор в значительной степени избыточен и не рекомендуется для общих целей. Строковый конструктор с аргументом String редко используется, кроме как для создания независимой копии существующей строковой переменной. В основном использовать его для "уточнения" вашего кода. Не меньше.
Ответ 5
из 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){.....}
Ответ 6
Вы используете его, если вам нужна копия исходной строки, если вы не хотите указывать дескриптор исходной строки. Но поскольку строки неизменяемы, я не вижу случая использования fot this;)