JavaRush /Blog Java /Random-MS /Terjemahan: Mencipta objek String dalam Java - menggunaka...
FellowSparrow
Tahap
Lvov

Terjemahan: Mencipta objek String dalam Java - menggunakan " " atau pembina?

Diterbitkan dalam kumpulan
Asal: Cipta Rentetan Java Menggunakan “ ” atau Pembina? Oleh X Wang Terjemahan: Mencipta Objek Rentetan dalam Java - PenggunaanDi Java, rentetan boleh dibuat menggunakan dua kaedah:
String x = "abc";
String y = new String("abc");
Apakah perbezaan antara menggunakan petikan berganda dan menggunakan pembina?

1. Petikan Berganda lwn. Pembina

Soalan ini boleh dijawab dengan melihat dua contoh mudah. Contoh 1:
String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
a==bbenar kerana akedua-duanya bmerujuk kepada objek yang sama - rentetan yang diisytiharkan sebagai literal (rentetan literal di bawah) dalam kawasan kaedah (kami merujuk pembaca kepada sumber pada sumber kami: Gambar rajah 8 teratas untuk memahami Java , rajah 8). Apabila literal rentetan yang sama dibuat lebih daripada sekali, hanya satu salinan rentetan disimpan dalam ingatan, hanya satu contoh daripadanya (dalam kes kami "abcd"). Ini dipanggil "interning string". Semua pemalar rentetan yang diproses pada masa penyusunan secara automatik dimasukkan ke dalam Java. Contoh 2:
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True
c==dpalsu kerana cia dmerujuk kepada dua objek berbeza dalam ingatan (pada timbunan). Objek yang berbeza sentiasa mempunyai rujukan yang berbeza. Rajah ini menggambarkan dua situasi yang diterangkan di atas: Terjemahan: Mencipta Objek Rentetan dalam Java - Penggunaan

2. Interning rentetan semasa pelaksanaan program

Penulis mengucapkan terima kasih kepada LukasEder (komen di bawah adalah miliknya): String interning juga boleh berlaku semasa pelaksanaan program, walaupun dua rentetan dibuat menggunakan pembina:
String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d);  // Now true
System.out.println(c.equals(d)); // True

3. Bila hendak menggunakan petikan berganda dan bila hendak menggunakan pembina

Disebabkan fakta bahawa "abcd" literal sentiasa daripada jenis String, menggunakan pembina akan mencipta objek tambahan yang tidak diperlukan. Jadi petikan berganda harus digunakan jika anda hanya perlu mencipta rentetan. Jika anda benar-benar perlu mencipta objek baharu pada timbunan, anda harus menggunakan pembina. Kes penggunaan ditunjukkan di sini (asal) . (Saya menyediakan teks terjemahan di bawah. Tetapi saya masih sangat mengesyorkan agar anda membiasakan diri dengan kod pengulas di pautan ini.)

Kaedah subrentetan() dalam JDK 6 dan JDK 7

Kaedah subrentetan() dalam JDK 6 dan JDK 7 Oleh X Wang Kaedah substring(int beginIndex, int endIndex)dalam JDK 6 dan JDK 7 adalah berbeza. Mengetahui perbezaan ini boleh membantu anda menggunakan kaedah ini dengan lebih baik. Demi kemudahan membaca, di bawah ini substring()kami maksudkan sintaks penuh, i.e. substring(int beginIndex, int endIndex).

1. Apakah yang dilakukan oleh substring()?

Kaedah ini substring(int beginIndex, int endIndex)mengembalikan rentetan yang bermula dengan nombor aksara beginIndexdan berakhir dengan nombor aksara endIndex-1.
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
Pengeluaran:
bc

2. Apakah yang berlaku apabila substring() dipanggil?

Anda mungkin tahu bahawa, disebabkan oleh kebolehubahan x, apabila menetapkan x hasil daripada x.substring(1,3), xia menunjuk kepada baris yang benar-benar baharu (lihat rajah): Terjemahan: Mencipta Objek Rentetan dalam Java - PenggunaanWalau bagaimanapun, rajah ini tidak betul sepenuhnya; ia tidak menunjukkan apa yang sebenarnya berlaku dalam timbunan. Apa yang sebenarnya berlaku apabila dipanggil substring()berbeza dalam JDK 6 dan JDK 7.

3. subrentetan() dalam JDK 6

Jenis rentetan disokong oleh jenis tatasusunan char. Dalam JDK 6, kelas Stringmengandungi 3 medan: char value[], int offset, int count. Ia digunakan untuk menyimpan tatasusunan sebenar aksara, indeks aksara pertama dalam tatasusunan, bilangan aksara dalam baris. Apabila kaedah dipanggil substring(), ia mencipta baris baharu, tetapi nilai pembolehubah masih menunjuk kepada tatasusunan yang sama pada timbunan. Perbezaan antara dua rentetan ialah bilangan aksaranya dan nilai indeks aksara permulaan dalam tatasusunan. Terjemahan: Mencipta Objek Rentetan dalam Java - PenggunaanKod di bawah dipermudahkan dan hanya mengandungi asas untuk menunjukkan masalah.
//JDK 6
String(int offset, int count, char value[]) {
	this.value = value;
	this.offset = offset;
	this.count = count;
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

4. Masalah yang disebabkan oleh substring() dalam JDK 6

Jika anda mempunyai rentetan yang SANGAT panjang, tetapi anda hanya memerlukan sebahagian kecil daripadanya, yang anda dapat setiap kali menggunakan substring(). Ini akan menyebabkan masalah pelaksanaan, kerana anda hanya memerlukan sebahagian kecil, tetapi anda masih perlu menyimpan keseluruhan rentetan. Untuk JDK 6, penyelesaiannya ialah kod di bawah, yang akan menghantar rentetan ke subrentetan sebenar:
x = x.substring(x, y) + ""
Pengguna STepeR merumuskan soalan (lihat ulasannya), dan nampaknya perlu menambah titik 4. "Masalah yang disebabkan substring()dalam JDK 6" ialah contoh yang lebih luas. Saya harap ini akan menjadi jawapan dan akan membantu orang lain dengan cepat mengetahui masalahnya. Inilah kodnya:
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
Jadi, dalam JDK 7 b, objek сjenis a Stringdicipta dengan memanggil kaedah substring()pada objek jenis a Stringakan merujuk dua tatasusunan yang baru dibuat dalam timbunan - Luntuk b, ongLuntuk c. Kedua-dua tatasusunan baharu ini akan disimpan pada timbunan BERSAMA-SAMA dengan tatasusunan asal aLongLongStringyang dirujuk oleh a. Itu. tatasusunan asal tidak hilang di mana-mana. Sekarang mari kembali ke JDK 6. Dalam JDK 6, timbunan mengandungi satu tatasusunan aLongLongString. Selepas melaksanakan baris kod
String b = a.substring(1, 2);
String c = a.substring(2, 6);
objek bmerujuk ckepada tatasusunan yang sama dalam timbunan, sepadan dengan objek a: b- kepada elemen dari indeks pertama hingga ke-2, c- kepada elemen dari indeks ke-2 hingga ke-6 (penomboran bermula dari 0, peringatan). Itu. Jelas sekali, sebarang akses lanjut kepada pembolehubah batau c dalam JDK 6 sebenarnya akan menyebabkan elemen yang dikehendaki bagi tatasusunan asal "dikira" ke dalam timbunan. Dalam JDK 7, sebarang akses lanjut kepada pembolehubah batau c akan menyebabkan akses kepada tatasusunan yang lebih kecil yang diperlukan yang telah dibuat dan "hidup" dalam timbunan. Itu. Jelas sekali JDK 7 menggunakan lebih banyak ingatan secara fizikal dalam situasi seperti ini. Tetapi mari kita bayangkan pilihan yang mungkin: subrentetan tertentu pembolehubah diberikan kepada pembolehubah b, dan pada masa hadapan semua orang hanya menggunakan mereka - objek dan . Tiada siapa yang hanya mengakses pembolehubah a lagi; tiada rujukan kepadanya (inilah maksud pengarang artikel). Akibatnya, pada satu ketika, pemungut sampah dicetuskan, dan (dalam bentuk yang paling umum, sudah tentu) kita mendapat 2 situasi berbeza: JDK 6 : objek dimusnahkan (sampah dikumpul) , TETAPI - besar asal array dalam timbunan masih hidup; ia sentiasa digunakan dan . JDK 7: objek a dimusnahkan bersama tatasusunan asal dalam timbunan. Detik ini dalam JDK 6 boleh menyebabkan kebocoran ingatan. cabcabc

5. subrentetan() dalam JDK 7

Kaedah ini telah ditambah baik dalam JDK 7. Dalam JDK 7 substring()ia sebenarnya mencipta tatasusunan baharu pada timbunan. Terjemahan: Mencipta Objek Rentetan dalam Java - Penggunaan
//JDK 7
public String(char value[], int offset, int count) {
	//check boundary
	this.value = Arrays.copyOfRange(value, offset, offset + count);
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	int subLen = endIndex - beginIndex;
	return new String(value, beginIndex, subLen);
}
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION