JavaRush /Java Blog /Random-ID /Terjemahan: Membuat objek String di Java - menggunakan " ...
FellowSparrow
Level 12
Lvov

Terjemahan: Membuat objek String di Java - menggunakan " " atau konstruktor?

Dipublikasikan di grup Random-ID
Asli: Membuat String Java Menggunakan “ ” atau Konstruktor? Oleh X Wang Terjemahan: Membuat Objek String di Java - PenggunaanDi Java, sebuah string dapat dibuat menggunakan dua metode:
String x = "abc";
String y = new String("abc");
Apa perbedaan antara menggunakan tanda kutip ganda dan menggunakan konstruktor?

1. Kutipan Ganda vs. Konstruktor

Pertanyaan ini dapat dijawab dengan melihat dua contoh sederhana. Contoh 1:
String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
a==bbenar karena akeduanya bmerujuk ke objek yang sama - string yang dideklarasikan sebagai literal (string literal di bawah) di area metode (kami merujuk pembaca ke sumber di sumber kami: 8 diagram teratas untuk memahami Java , diagram 8). Ketika literal string yang sama dibuat lebih dari sekali, hanya satu salinan string yang disimpan di memori, hanya satu instance saja (dalam kasus kita "abcd"). Ini disebut "string magang". Semua konstanta string yang diproses pada waktu kompilasi secara otomatis diinternir di 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==dfalse karena cmerujuk dpada dua objek berbeda di memori (di heap). Objek yang berbeda selalu memiliki referensi yang berbeda. Diagram ini menggambarkan dua situasi yang dijelaskan di atas: Terjemahan: Membuat Objek String di Java - Penggunaan

2. Interning string pada tahap eksekusi program

Penulis berterima kasih kepada LukasEder (komentar di bawah ini adalah miliknya): Interning string juga dapat terjadi selama eksekusi program, bahkan jika dua string dibuat menggunakan konstruktor:
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. Kapan menggunakan tanda kutip ganda dan kapan menggunakan konstruktor

Karena kenyataan bahwa "abcd" literal selalu bertipe String, menggunakan konstruktor akan membuat objek tambahan yang tidak diperlukan. Jadi tanda kutip ganda sebaiknya digunakan jika Anda hanya perlu membuat string. Jika Anda benar-benar perlu membuat objek baru di heap, Anda harus menggunakan konstruktor. Kasus penggunaan ditampilkan di sini (asli) . (Saya menyediakan teks terjemahan di bawah. Namun saya tetap sangat menyarankan Anda membiasakan diri dengan kode komentator di tautan ini.)

Metode substring() di JDK 6 dan JDK 7

Metode substring() di JDK 6 dan JDK 7 Oleh X Wang Metode substring(int beginIndex, int endIndex)di JDK 6 dan JDK 7 berbeda. Mengetahui perbedaan ini dapat membantu Anda menggunakan metode ini dengan lebih baik. Demi kemudahan membaca, di bawah ini substring()kami maksudkan sintaks lengkapnya, yaitu. substring(int beginIndex, int endIndex).

1. Apa yang dilakukan substring()?

Metode ini substring(int beginIndex, int endIndex)mengembalikan string yang dimulai dengan nomor karakter beginIndexdan diakhiri dengan nomor karakter endIndex-1.
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
Keluaran:
bc

2. Apa yang terjadi jika substring() dipanggil?

Anda mungkin tahu bahwa, karena kekekalan x, ketika menetapkan x hasil dari x.substring(1,3), xia menunjuk ke baris yang benar-benar baru (lihat diagram): Terjemahan: Membuat Objek String di Java - PenggunaanNamun, diagram ini tidak sepenuhnya benar; itu tidak menunjukkan apa yang sebenarnya terjadi di heap. Apa yang sebenarnya terjadi ketika dipanggil substring()berbeda di JDK 6 dan JDK 7.

3. substring() di JDK 6

Tipe string didukung oleh tipe array char. Di JDK 6, kelas Stringberisi 3 bidang: char value[], int offset, int count. Mereka digunakan untuk menyimpan array karakter sebenarnya, indeks karakter pertama dalam array, jumlah karakter dalam baris. Saat metode ini dipanggil substring(), ia akan membuat baris baru, namun nilai variabelnya masih mengarah ke larik yang sama di heap. Perbedaan antara dua string adalah jumlah karakternya dan nilai indeks karakter awal dalam array. Terjemahan: Membuat Objek String di Java - PenggunaanKode di bawah ini disederhanakan dan hanya berisi dasar-dasar untuk menunjukkan masalahnya.
//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() di JDK 6

Jika Anda memiliki string yang SANGAT panjang, tetapi Anda hanya membutuhkan sebagian kecil saja, yang Anda dapatkan setiap kali menggunakan substring(). Hal ini akan menyebabkan masalah eksekusi, karena Anda hanya memerlukan sebagian kecil, tetapi Anda tetap harus menyimpan keseluruhan string. Untuk JDK 6, solusinya adalah kode di bawah ini, yang akan mentransmisikan string ke substring sebenarnya:
x = x.substring(x, y) + ""
Pengguna STepeR merumuskan pertanyaan (lihat komentarnya), dan sepertinya perlu menambahkan poin 4. "Masalah yang disebabkan substring()di JDK 6" adalah contoh yang lebih luas. Saya harap ini akan menjadi jawabannya dan membantu orang lain dengan cepat mengetahui apa masalahnya. Berikut kodenya:
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
Jadi, di JDK 7 b, objek сbertipe a Stringyang dibuat dengan memanggil metode substring()pada objek bertipe a Stringakan mereferensikan dua array yang baru dibuat di heap - Lfor b, ongLfor c. Kedua array baru ini akan disimpan di heap BERSAMA dengan array asli aLongLongStringyang direferensikan oleh a. Itu. array asli tidak hilang kemana-mana. Sekarang mari kita kembali ke JDK 6. Di JDK 6, heap berisi satu array aLongLongString. Setelah mengeksekusi baris kode
String b = a.substring(1, 2);
String c = a.substring(2, 6);
objek bmengacu cpada array yang sama di heap, sesuai dengan objek a: b- ke elemen dari indeks ke-1 hingga ke-2, c- ke elemen dari indeks ke-2 hingga ke-6 (penomoran dimulai dari 0, pengingat). Itu. Jelasnya, akses lebih lanjut ke variabel batau c di JDK 6 sebenarnya akan mengakibatkan elemen yang diinginkan dari array asli “dihitung” ke dalam heap. Di JDK 7, akses lebih lanjut ke variabel batau c akan menyebabkan akses ke array kecil yang diperlukan yang telah dibuat dan “hidup” di heap. Itu. Jelas JDK 7 menggunakan lebih banyak memori secara fisik dalam situasi seperti ini. Tapi mari kita bayangkan opsi yang mungkin: substring tertentu dari variabel ditugaskan ke variabel b, dan di masa depan semua orang hanya menggunakan substring tersebut - objek dan . Tidak ada seorang pun yang mengakses variabel a lagi; tidak ada referensi ke sana (inilah maksud penulis artikel). Akibatnya, pada suatu saat pengumpul sampah dipicu, dan (dalam bentuk paling umum, tentu saja) kita mendapatkan 2 situasi berbeda: JDK 6 : objek dihancurkan (sampah dikumpulkan) , TETAPI - array besar asli di tumpukan itu masih hidup; itu terus-menerus digunakan dan . JDK 7: objek a dihancurkan bersama dengan array asli di heap. Inilah poin di JDK 6 yang dapat menyebabkan kebocoran memori. cabcabc

5. substring() di JDK 7

Metode ini telah ditingkatkan di JDK 7. Di JDK 7 substring()sebenarnya membuat array baru di heap. Terjemahan: Membuat Objek String di 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);
}
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION