Bagaimana saya harus menyalin Strings di Java?


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

Pada titik ini, variabel cadangan masih berisi nilai asli "halo" (ini karena kekekalan String kan?).

Tetapi apakah benar - benar aman untuk menyalin Strings dengan metode ini (yang tentu saja tidak aman untuk menyalin objek yang bisa berubah-ubah), atau lebih baik untuk menulis ini? :

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

Dengan kata lain, apa bedanya (jika ada) antara kedua cuplikan ini?


EDIT - alasan mengapa cuplikan pertama aman:

Izinkan saya menjelaskan hal-hal dengan sedikit lebih detail, berdasarkan jawaban baik yang sudah disediakan (yang pada dasarnya berfokus pada pertanyaan tentang perbedaan kinerja antara 2 cuplikan):

String tidak dapat diubah di Jawa, yang berarti bahwa objek String tidak dapat dimodifikasi setelah konstruksinya. Karenanya,

String s = "hello";membuat instance String baru dan memberikan alamatnya s( smenjadi referensi ke instance / objek)

String backup_of_s = s;membuat variabel baru backup_of_sdan menginisialisasi sehingga referensi objek saat ini dirujuk oleh s.

Catatan: String immutability menjamin bahwa objek ini tidak akan diubah: cadangan kami aman

Catatan 2: Mekanisme pengumpulan sampah Java menjamin bahwa objek ini tidak akan dihancurkan asalkan direferensikan oleh setidaknya satu variabel ( backup_of_sdalam hal ini)

Akhirnya, s = "bye";buat instance String lain (karena ketidakmampuan, itu satu-satunya cara), dan memodifikasi svariabel sehingga sekarang referensi objek baru.

Jawaban:


139

Karena string tidak dapat diubah, kedua versi aman. Yang terakhir, bagaimanapun, kurang efisien (itu menciptakan objek tambahan dan dalam beberapa kasus menyalin data karakter).

Dengan pemikiran ini, versi pertama harus lebih disukai.


15
Kekekalan tidak ada hubungannya dengan itu. Ini hanyalah cara kerja referensi objek. Saya bisa memberikan contoh StringBuilder yang setara.
GriffeyDog

1
@ BalusC, saya tidak bisa melihat bagaimana String baru () dapat membuat apa pun di kumpulan String JVM. Hanya string string dan mereka yang berkomitmen ke pool melalui intern () yang ada di pool.
Snicolas

3
@ GeffeyDog: Saya membaca pertanyaan itu secara harfiah. Apa yang saya katakan adalah bahwa aman untuk memberikan referensi ke objek string tanpa takut seseorang mungkin memodifikasi string.
NPE

2
@GriffeyDog Saya menemukan komentar Anda sangat menyesatkan: ketidakmampuan adalah apa yang membuat potongan pertama aman, mengapa Anda mengatakan itu tidak ada hubungannya dengan "itu"?
Sébastien

5
@Sebastien Semua yang dilakukannya adalah menugaskan kembali variabel referensi suntuk merujuk ke objek yang berbeda ( String"bye"). Itu tidak mempengaruhi apa yang dirujuk oleh variabel referensi backup_of_s( String"halo"). Seperti yang saya katakan, saya bisa memberikan contoh yang setara dengan StringBuilders, yang tidak dapat diubah. Komentar saya terutama berkaitan dengan pernyataan OP: Pada titik ini, variabel cadangan masih berisi nilai asli "halo" (ini karena kekekalan String, kan?).
GriffeyDog

22

String adalah objek yang tidak dapat diubah sehingga Anda dapat menyalinnya hanya dengan mengatasinya, karena objek yang dirujuk tidak dapat berubah ...

Jadi, Anda dapat menyalin seperti pada contoh pertama Anda tanpa masalah:

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

10

Versi kedua Anda kurang efisien karena ia menciptakan objek string tambahan ketika tidak perlu melakukannya.

Kekekalan berarti bahwa versi pertama Anda berperilaku seperti yang Anda harapkan dan dengan demikian pendekatan yang lebih disukai.


0

Kasus kedua juga tidak efisien dalam hal kolam String, Anda harus secara eksplisit memanggil magang () pada referensi kembali untuk membuatnya magang.


-16
String str1="this is a string";
String str2=str1.clone();

Bagaimana dengan salinan seperti ini? Saya pikir untuk mendapatkan salinan baru lebih baik, sehingga data str1tidak akan terpengaruh ketika str2referensi dan dimodifikasi dalam tindakan selanjutnya.


3
Stringtidak kekal. mengkloning String tidak masuk akal.
Vladimir
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.