String s = "hello";
String backup_of_s = s;
s = "bye";
На этом этапе переменная резервной копии все еще содержит исходное значение «привет» (это из-за неизменности в String, верно?).
Но действительно ли безопасно копировать строки этим методом (что, конечно, небезопасно копировать обычные изменяемые объекты), или лучше написать это? :
String s = "hello";
String backup_of_s = new String(s);
s = "bye";
Другими словами, в чем разница (если есть) между этими двумя фрагментами?
РЕДАКТИРОВАТЬ - причина, по которой первый фрагмент безопасен:
Позвольте мне объяснить некоторые вещи немного подробнее, основываясь на уже предоставленных хороших ответах (которые были в основном сфокусированы на вопросе различий в производительности между двумя фрагментами):
Строки являются неизменяемыми в 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
переменную так, чтобы она теперь ссылалась на новый объект.
s
для ссылки на другой объект (String
«пока»). Это не влияет на то, на что ссылается ссылочная переменнаяbackup_of_s
(String
«привет»). Как я уже сказал, я мог бы предоставить эквивалентный пример сStringBuilder
s, который не является неизменным. Мой комментарий в основном касается оператора OP: на данный момент резервная переменная все еще содержит исходное значение «привет» (это из-за неизменности в String?).Строки являются неизменяемыми объектами, поэтому вы можете скопировать их, просто скопировав ссылку на них, потому что объект, на который ссылаются, не может измениться ...
Таким образом, вы можете скопировать как в первом примере без проблем:
источник
Ваша вторая версия менее эффективна, потому что она создает дополнительный строковый объект, когда в этом просто нет необходимости.
Неизменность означает, что ваша первая версия ведет себя так, как вы ожидаете, и, таким образом, предпочтительным является подход.
источник
Второй случай также неэффективен с точки зрения пула строк, вы должны явно вызвать intern () при возврате ссылки, чтобы сделать его интерном.
источник
Как насчет копирования, как это? Я думаю, что получить новую копию лучше, так что данные
str1
не будут затронуты, когдаstr2
будут ссылаться и изменяться в дальнейшем действии.источник
String
неизменен. Строки клонирования не имеют особого смысла.