Как мне скопировать строки в Java?

    String s = "hello";
    String backup_of_s = s;
    s = "bye";

На этом этапе переменная резервной копии все еще содержит исходное значение «привет». (это из-за неизменности String, верно?).

Но так ли это?safe копировать строки с помощью этого метода (который, конечно, небезопасно копировать обычные изменяемые объекты), или лучше написать это? :

    String s = "hello";
    String backup_of_s = new String(s);
    s = "bye";

Другими словами, в чем разница (если таковая имеется) между этими двумя фрагментами?

EDIT - the reason why the first snippet is safe:

Позвольте мне объяснить некоторые вещи немного подробнее, основываясь на уже предоставленных хороших ответах (которые были в основном сфокусированы на вопросе различий в производительности между двумя фрагментами):

Строки являются неизменяемыми в Java, что означает, что объект String не может быть изменен после его создания. Следовательно,

String s = "hello"; создает новый экземпляр String и назначает его адресs (s являясь ссылкой на экземпляр / объект)

String backup_of_s = s; создает новую переменнуюbackup_of_s и инициализирует его так, чтобы он ссылался на объект, на который в данный момент ссылаетсяs.

Примечание: неизменность строки гарантирует, что этот объект не будет изменен: наша резервная копия безопасна

Примечание 2: Механизм сборки мусора Java гарантирует, что этот объект не будет уничтожен, если на него ссылается хотя бы одна переменная (backup_of_s в этом случае)

В заключение,s = "bye"; создает другой экземпляр String (из-за неизменности, это единственный способ) и изменяетs переменная, так что теперь она ссылается на новый объект.

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

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

обе версии безопасны. Последний, однако, менее эффективен (он создает дополнительный объект и в некоторых случаях копирует символьные данные).

Учитывая это, первая версия должна быть предпочтительной.

 Snicolas15 мая 2012 г., 22:12
@ BalusC, я не вижу, как new String () может создать что-либо в пуле String JVM. В него входят только строковые литералы и те, которые были переданы в пул с помощью intern ().
 NPE15 мая 2012 г., 22:12
@ GriffeyDog: я читаю вопрос менее буквально. Я говорю о том, что можно безопасно давать ссылки на строковый объект, не опасаясь, что кто-то может изменить строку.
 Sébastien21 мар. 2014 г., 15:46
@ GriffeyDog Я нахожу ваш комментарий очень вводящим в заблуждение: неизменность - это то, что делает первый фрагмент безопасным, почему вы говорите, что оно не имеет ничего общего с «этим»?
 GriffeyDog21 мар. 2014 г., 16:25
@ Sebastien Все, что он делает, это переназначает ссылочную переменнуюs для ссылки на другой объект (символString "до свидания"). Это не влияет на то, что ссылочная переменнаяbackup_of_s имеет в виду String "Здравствуйте"). Как я уже сказал, я мог бы привести эквивалентный пример сStringBuilders, которыйн неизменный. Мой комментарий в основном касается заявления ОП: На данный момент резервная переменная по-прежнему содержит исходное значение «привет» (это из-за неизменности права String?).
 GriffeyDog15 мая 2012 г., 22:11
Неизменность не имеет к этому никакого отношения. Это просто, как работают ссылки на объекты. Я мог бы предоставить эквивалентный пример StringBuilder.

потому что она создает дополнительный строковый объект, когда в этом просто нет необходимости.

Immutability означает, что ваша первая версия ведет себя так, как вы ожидаете, и, таким образом, это предпочтительный подход.

вы должны явно вызвать intern () при возврате ссылки, чтобы сделать его интерном.

immutable objects так что вы можете скопировать их, просто скопировав ссылку на них, потому что объект, на который ссылаются, не может измениться ...

Так что вы можете без проблем скопировать, как в первом примере:

String s = "hello";
String backup_of_s = s;
s = "bye";
String str1="this is a string";
String str2=str1.clone();

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

 Stimpson Cat05 апр. 2018 г., 15:30
Хорошая шутка, но плохой ответ
 Vladimir08 мая 2013 г., 15:02
String неизменен. Клонирование строк не имеет особого смысла.
 glen3b07 июн. 2014 г., 18:23
String.clone() даже не существует ...

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