Kata pengantar
Artikel ini terutama memperkenalkan konten yang relevan tentang analisis kode sumber JDK, StringBuilder dan StringBuffer. Ini dibagikan untuk referensi dan pembelajaran Anda. Saya tidak akan mengatakan banyak hal di bawah. Mari kita lihat perkenalan terperinci bersama -sama.
Pernyataan Kelas String
String kelas akhir publik mengimplementasikan java.io.serializable, sebanding <string>, charsequence {...}Kelas string menggunakan pengubah akhir untuk menunjukkan bahwa itu tidak dapat diwarisi. Pada saat yang sama, ini juga mengimplementasikan tiga antarmuka, menerapkan antarmuka yang dapat diserialisasi untuk menunjukkan bahwa kelas string dapat diserialisasi; Menerapkan antarmuka <T> yang sebanding terutama menyediakan metode compareto untuk membandingkan string string; Juga mengimplementasikan antarmuka charsequence, yang menyatakan bahwa char bernilai urutan yang dapat dibaca (charbuffer, segmen, string, stringbuffer, dan stringbuilder juga mengimplementasikan antarmuka charsequence)
Bidang utama string dan deskripsi atribut
/*Nilai Array Karakter, Menyimpan karakter aktual dalam nilai string*/private final char [];/*Nilai hash dari nilai default string 0*/private int hash; /*Nilai hash dari nilai default string 0*//*Komparator, yang digunakan untuk mengurutkan objek string, metode compareToignoRecase menggunakan*/komparator final statis public <string> case_insensitive_order = new caseInsensitiveComparator ();
Analisis metode parsial string
Kelas string menyediakan serangkaian konstruktor, dan beberapa di antaranya tidak lagi direkomendasikan, seperti yang ditunjukkan pada gambar di bawah ini:
Konstruktor
Berikut adalah implementasi dua konstruktor yang umum digunakan:
// string str = string baru ("123") public string (string asli) {this.value = original.value; this.hash = original.hash;} // string str3 = string baru (char baru [] {'1', '2', '3'}); string publik (nilai char []) {// salin nilai array karakter untuk menilai this.value = arrays.copyof (value, value.length); }boolean sama (objek anobject)
Kelas string menimpa metode Equals untuk membandingkan string ini dengan objek yang ditentukan. Hasilnya benar jika dan hanya jika parameter tidak nol dan merupakan objek string yang mewakili urutan karakter yang sama dengan objek ini.
Public Boolean Equals (Object Anobject) {// Bandingkan referensi objek secara langsung, dan return true if (this == anObject) {return true; } // Bandingkan urutan karakter dari objek saat ini dengan nilai anobject if (anObject instance dari string) {string anotherstring = (string) anObject; int n = value.length; if (n == anotherstring.value.length) {char v1 [] = nilai; char v2 [] = anotherstring.value; int i = 0; while (n--! = 0) {if (v1 [i]! = v2 [i]) mengembalikan false; i ++; } return true; }} return false; }int compareto (string anotherstring)
Bandingkan urutan karakter dari dua string bit demi bit. Jika karakter bit tidak sama, kembalikan perbedaan dalam nilai unicode dari dua karakter bit itu. Semua bit sama, hitung perbedaan panjang dua string. Jika kedua stringnya sama, kembalikan 0.
compareto int publik (string anotherstring) {int len1 = value.length; int len2 = anotherstring.value.length; // Ambil panjang string dengan panjang int lim = math.min (len1, len2); char v1 [] = nilai; char v2 [] = anotherstring.value; int k = 0; while (k <lim) {// Bandingkan nilai urutan karakter dari dua string satu per satu. Jika tidak sama, kembalikan perbedaan antara unicode dari dua karakter pada posisi itu char c1 = v1 [k]; char c2 = v2 [k]; if (c1! = c2) {return c1 - c2; // Kembalikan perbedaan antara Unicode} K ++; } // Semua bit dari string yang lebih kecil dibandingkan, dan perbedaan antara panjang dua string dikembalikan // Jika kedua stringnya sama, perbedaan antara panjangnya adalah 0, yaitu, string yang sama mengembalikan 0 return len1 - len2; } Metode comparetoignorecase (string str) diimplementasikan dengan cara yang sama. Kasing karakter atas dan bawah diabaikan selama perbandingan, dan metode implementasinya adalah sebagai berikut:
Public int Compare (String S1, String S2) {int n1 = s1.length (); int n2 = s2.length (); int min = math.min (n1, n2); untuk (int i = 0; i <min; i ++) {char c1 = s1.charat (i); char c2 = s2.charat (i); if (c1! = c2) {c1 = karakter.touppercase (c1); C2 = karakter.tuppercase (C2); if (c1! = c2) {c1 = karakter.tolowercase (c1); c2 = karakter.tolowercase (C2); if (c1! = c2) {// tidak ada overflow karena promosi numerik return c1 - c2; }}}} return n1 - n2; }Native String Intern ()
Ketika metode magang dipanggil, jika kumpulan sudah berisi string yang sama dengan objek string ini (ditentukan dengan metode Equals (objek)), string di kumpulan dikembalikan. Jika tidak, tambahkan objek string ini ke kumpulan dan kembalikan referensi ke objek string ini.
Semua string literal dan ekspresi konstan penugasan string dioperasikan menggunakan metode magang, misalnya: string str1 = "123";
Lokasi memori string: pool atau heap konstan
Objek string dapat dibuat secara langsung melalui literal atau melalui konstruktor. Apa bedanya?
1. Objek string yang dibuat oleh string literal atau literal melalui "+" splicing disimpan di kolam konstan. Jika kumpulan konstan ada selama penciptaan aktual, referensi akan dikembalikan langsung. Jika tidak ada, objek string akan dibuat.
2. Buat objek string menggunakan konstruktor, dan buat objek string secara langsung di heap
3. Panggil metode magang, dan kembalikan objek akan dimasukkan ke dalam kumpulan konstan (jika tidak ada, itu akan ditempatkan ke dalam kolam konstan, dan jika memang ada, itu akan dikembalikan ke referensi)
Berikut ini adalah contoh alokasi memori objek string:
String str1 = string baru ("123"); String str2 = "123"; String str3 = "123"; String str4 = str1.intern (); System.out.println (str1 == str2); // False Str1 membuat objek di heap, str2 membuat objek di konstanta pool system.out.println (str2 == str3); // True Str2 membuat objek di kumpulan konstan, STR3 secara langsung mengembalikan referensi ke objek yang dibuat oleh STR2, sehingga STR2 dan STR3 menunjuk ke objek yang sama di System Pool Constant.out.println (str4 == Str3); // True Str4 mengembalikan objek dengan nilai "123" di kolam konstan, jadi STR4, STR2 dan STR3 sama.Tentang Contoh Jahitan String:
Public Class StringTest {Public Static Final String x = "ABC"; // konstan x @test public void test () {string str5 = string baru ("abc"); String str6 = str5+"def"; // buat string str7 = "abc"+"def"; // string pool konstan str8 = x+"def"; // x adalah konstan, dan nilainya tetap, sehingga nilai x+"def" telah diatur ke ABCDEF. Bahkan, setelah kompilasi, kode setara dengan string str8 = "abcdef" string str9 = "abc"; String str10 = str9+"def"; //System.out.println(str6==str7); // false system.out.println (str8 == str7); // true system.out.println (str10 == str7); // false system.out.println (x == str9); //BENAR} }Kode yang didekompilasi akan jelas sekilas:
Alokasi memori adalah sebagai berikut:
String, StringBuffer, StringBuilder
Karena nilai properti [] array karakter untuk menyimpan string yang dikelola secara internal berdasarkan jenis string dimodifikasi dengan final:
/** Nilainya digunakan untuk penyimpanan karakter. */nilai arang akhir pribadi [];
Ini menunjukkan bahwa itu dapat dimodifikasi setelah penugasan. Karena itu, kami percaya bahwa objek string tidak dapat diubah begitu dibuat. Jika Anda sering menghadapi operasi string splicing selama pengembangan, jika Anda menggunakan kontak yang disediakan oleh string atau menggunakan string splicing "+" secara langsung, string baru akan sering dihasilkan, yang tidak efisien. Java menyediakan dua kelas lain: StringBuffer dan StringBuilder, yang digunakan untuk menyelesaikan masalah ini:
Lihatlah kode berikut:
String str1 = "123"; String str2 = "456"; String str3 = "789"; String str4 = "123" + "456" + "789"; // Tambahkan konstanta, kompiler secara otomatis mengenali string str4 = "123456789" string str5 = str1 + str2 + str3; // stand string variable splicing, disarankan untuk menggunakan StringBuilder StringBuilder SB = New StringBuilder (); SB.Append (str1); SB.Append (str2); SB.Append (str3);
Berikut ini adalah implementasi kelas StringBuilder, yang hanya mencegat beberapa kode yang dianalisis:
Public Final Class StringBuilder memperluas AbstractStringBuilder mengimplementasikan java.io.serializable, charsequence {// split string @Override public stringBuilder append (string str) {// memanggil kelas induk abstractStringBuilder.append super.append (str); kembalikan ini; }} Kelas Abstrak AbstractStringBuilder mengimplementasikan yang dapat ditambahkan, charsequence { / *** Array karakter yang menyimpan string, tipe non-final, berbeda dari nilai string class* / char []; /*** Hitungannya adalah jumlah karakter yang digunakan. */ jumlah int; public abstractStringBuilder append (string str) {if (str == null) return appendNull (); int len = str.length (); // Periksa apakah kapasitas perlu diperluas ke Ensurecapacityinternal (Count + Len); // Salin string str string ke value str.getchars (0, len, value, count); hitung += len; return ini;} private void ensurecapacityinternal (int minimumcapacity) {// overflow -consent code // minimumCapacity = count+str.length // jika kapasitas setelah str disambung lebih besar dari kapasitas nilai, dan kopel nilai kini, nilai minimum - value. Arrays.copyof (nilai, newcapacity (minimumcapacity)); }} // StringBuilder Ekspansi Private Int Newcapacity (int MinCapacity) {// overflow-conseous code // Hitung kapasitas ekspansi // Panjang array ekspansi default diperluas 2 kali lipat dari angka asli (nilai []) panjang grup dan kemudian 2 ditambahkan ke aturan. Mengapa menambahkan 2? int newcapacity = (value.length << 1) + 2; if (newcapacity - mintcapacity <0) {newCapacity = mincapacity; } return (newCapacity <= 0 || max_array_size - newCapacity <0)? HugeCapacity (MinCapacity): Newcapacity; }}Hal yang sama berlaku untuk StringBuffer dan StringBuilder. Nilai [] array karakter yang dipertahankan secara internal dapat berubah. Satu-satunya perbedaan adalah bahwa StringBuffer aman. Itu menyinkronkan semua metode. StringBuilder tidak aman. Oleh karena itu, ketika operasi multi-threaded dan berbagi variabel string, StringBuffer lebih disukai untuk pemrosesan splicing string. Jika tidak, StringBuilder dapat digunakan. Bagaimanapun, sinkronisasi utas juga akan membawa konsumsi tertentu.
Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap konten artikel ini memiliki nilai referensi tertentu untuk studi atau pekerjaan semua orang. Jika Anda memiliki pertanyaan, Anda dapat meninggalkan pesan untuk berkomunikasi. Terima kasih atas dukungan Anda ke wulin.com.