Baru -baru ini, ketika saya mencari pekerjaan, pemeriksa mengajukan pertanyaan sederhana: "Perbedaan antara StringBuffer dan StringBuilder, apa skenario aplikasi mereka?" Jawaban editor dibagikan kepada Anda di bawah ini, sehingga dapat lebih mudah bagi semua orang untuk belajar di masa depan, sehingga dapat membuat catatan.
Faktanya, cari saja Google Master dan Anda akan memiliki jawabannya: StringBuffer sepenuhnya setara dengan metode dan fungsi di StringBuilder, tetapi sebagian besar metode di StringBuffer menggunakan kata kunci yang disinkronkan untuk modifikasi, sehingga mereka aman. Tanpa modifikasi ini, StringBuilder dapat dianggap tidak aman.
Untuk lebih memahami jawaban di atas, lebih baik secara langsung melihat bahwa implementasi kode sumber dari StringBuffer dan StringBuilder lebih realistis. Sebagai seorang programmer, "Jika Anda memiliki pertanyaan, lihat kode sumber" adalah cara yang benar. Saya bisa mengatakan secara bertanggung jawab, tentu saja, Anda harus memiliki kondisi!
Dalam implementasi JDK, baik StringBuffer dan StringBuilder diwarisi dari AbstractStringBuilder. Untuk keamanan dan tidak amannya multi-threading, Anda akan memiliki pemahaman kasar tentang metode yang disinkronkan di StringBuffer.
Di sini saya akan berbicara secara singkat tentang prinsip implementasi AbstractStringBuilder: kita tahu bahwa menggunakan StringBuffer tidak lebih dari meningkatkan efisiensi koneksi string di Java, karena jika Anda menggunakan + secara langsung untuk koneksi string, JVM akan membuat beberapa objek string, yang akan menyebabkan overhead tertentu. AbstractStringBuilder menggunakan array char untuk menyimpan string yang perlu ditambahkan. Array char memiliki ukuran awal. Ketika panjang string dari string append melebihi kapasitas array char saat ini, array char diperluas secara dinamis, yaitu, menampilkan kembali ruang memori yang lebih besar, dan kemudian menyalin array char saat ini ke lokasi baru. Karena overhead memori yang mengalokasikan kembali dan penyalinan relatif besar, setiap kali Anda menggunakan kembali ruang memori adalah cara ruang memori lebih besar dari arus yang dibutuhkan, yaitu 2 kali.
Selanjutnya, bersenang -senang!
Berikut beberapa informasi di Google:
【
StringBuffer dimulai dengan JDK 1.0
StringBuilder dimulai dengan JDK 1.5
Mulai dari JDK 1.5, operasi koneksi (+) dengan variabel string digunakan secara internal oleh JVM
StringBuilder diimplementasikan, dan operasi ini diimplementasikan menggunakan StringBuffer.
】
Kami melihat proses eksekusi melalui program sederhana:
Listing 1 buffer.java
buffer kelas publik {public static void main (string [] args) {string s1 = "aaaaa"; String s2 = "bbbbbb"; String r = null; int i = 3694; R = S1 + I + S2; untuk (int j = 0; i <10; j ++) {r+= "23124"; }}}Gunakan perintah javap -c buffer untuk melihat implementasi bytecode -nya:
Listing 2 Buffer Class Bytecode
Daftar yang sesuai 1 dan Daftar 2, instruksi LDC di Daftar 2 memuat string "AAAA" dari kumpulan konstan ke bagian atas tumpukan, dan iStore_1 menyimpan "AAAAA" dalam variabel 1. Berikut ini adalah sama. Sipush mendorong nilai konstan integer pendek (-32768 ~ 32767) ke bagian atas tumpukan. Inilah "3694" yang konstan. Untuk set instruksi Java lainnya, silakan periksa artikel lain "Set Instruksi Java".
Mari kita langsung melihat bahwa 13, 13 ~ 17 adalah hal baru untuk objek StringBuffer dan memanggil metode inisialisasi. 20 ~ 21 adalah untuk pertama menekan variabel 1 ke bagian atas tumpukan melalui aload_1. Seperti disebutkan sebelumnya, variabel 1 dimasukkan ke dalam string konstanta "aaaaa", dan kemudian memanggil metode append dari stringbuffer melalui instruksi invokevirtual untuk menyatukan "aaaaa" bersama -sama. 24 ~ 30 berikut adalah sama. Akhirnya, pada 33, fungsi ToString dari StringBuffer dipanggil untuk mendapatkan hasil string dan disimpan dalam variabel 3 melalui toko.
Ketika kita melihat ini, seseorang mungkin berkata, "Karena JVM menggunakan StringBuffer untuk menghubungkan string, kita tidak perlu menggunakan StringBuffer sendiri, cukup gunakan"+"Just!" Apakah itu benar? Tentu saja tidak. Seperti kata pepatah, "ada alasan untuk keberadaan", mari kita terus melihat bytecode yang sesuai dengan loop berikutnya.
37 ~ 42 adalah beberapa persiapan sebelum memasuki loop untuk. 37, 38 Set J ke 1. 44 Di sini, IF_ICMPGE membandingkan J dengan 10. Jika J lebih besar dari 10, itu akan melonjak langsung ke 73, yaitu, pernyataan pengembalian keluar dari fungsi; Kalau tidak, ia memasuki loop, yaitu, bytecode 47 ~ 66. Di sini kita hanya perlu melihat 47 hingga 51 untuk mengetahui mengapa kita menggunakan StringBuffer dalam kode kita untuk menangani koneksi string, karena setiap kali kita melakukan operasi "+", JVM harus ke objek StringBuffer baru untuk menangani koneksi string, yang akan sangat mahal ketika banyak operasi koneksi string terlibat.