Masalah pengemasan dan unboxing otomatis adalah masalah umum di Java. Hari ini kita akan melihat beberapa masalah dalam pengepakan dan unboxing. Artikel ini pertama kali berbicara tentang hal -hal paling mendasar tentang pengemasan dan unboxing, dan kemudian lihat masalah yang berkaitan dengan pengemasan dan unboxing yang sering ditemui dalam tes tertulis di bawah ini.
1. Apa itu pengemasan? Apa itu Unboxing?
Dalam artikel sebelumnya, Java menyediakan jenis pembungkus yang sesuai untuk setiap tipe data dasar. Adapun mengapa jenis pembungkus disediakan untuk setiap tipe data dasar, itu tidak akan dijelaskan di sini. Teman yang tertarik dapat berkonsultasi dengan informasi yang relevan. Sebelum Java SE5, jika Anda ingin menghasilkan objek integer dengan nilai 10, Anda harus melakukan ini:
Salinan kode adalah sebagai berikut:
Integer i = bilangan bulat baru (10);
Sejak Java SE5, fitur tinju otomatis disediakan. Jika Anda ingin menghasilkan objek integer dengan nilai 10, Anda hanya perlu melakukan ini:
Salinan kode adalah sebagai berikut:
Integer I = 10;
Dalam proses ini, objek integer yang sesuai akan secara otomatis dibuat berdasarkan nilai numerik, yang sedang dikemas.
Jadi apa itu unboxing? Seperti namanya, itu sesuai dengan pengemasan, yang secara otomatis mengonversi tipe pembungkus ke tipe data dasar:
Salinan kode adalah sebagai berikut:
Integer I = 10; //sedang mengemas
int n = i; // unbox
Sederhananya, pengemasan berarti secara otomatis mengonversi tipe data dasar ke tipe pembungkus; Unboxing berarti secara otomatis mengonversi tipe pembungkus ke tipe data dasar.
Tabel berikut adalah tipe pembungkus yang sesuai dengan tipe data dasar:
2. Bagaimana pengemasan dan unboxing diimplementasikan?
Setelah memahami konsep dasar pengemasan di bagian sebelumnya, bagian ini akan memahami bagaimana pengemasan dan unboxing diimplementasikan.
Mari kita ambil kelas Interger sebagai contoh, dan lihat sepotong kode di bawah ini:
kelas publik utama {public static void main (string [] args) {integer i = 10; int n = i;}}Setelah mendekompilasi file kelas, Anda akan mendapatkan konten berikut:
Dari konten bytecode yang diperoleh dengan mendekompilasi, dapat dilihat bahwa metode integer nilai (int) secara otomatis dipanggil saat pengemasan. Saat unboxing, metode integer integer dipanggil secara otomatis.
Lainnya serupa, seperti ganda atau karakter. Teman -teman yang tidak percaya dapat mencobanya secara manual sendiri.
Oleh karena itu, proses implementasi pengemasan dan unboxing dapat diringkas dalam satu kalimat:
Proses tinju diimplementasikan dengan memanggil nilai metode pembungkus, sedangkan proses unboxing diimplementasikan dengan memanggil metode XXXValue dari pembungkus. (XXX mewakili tipe data dasar yang sesuai).
3. Pertanyaan Terkait Selama Wawancara
Meskipun kebanyakan orang jelas tentang konsep pengepakan dan unboxing, mereka mungkin tidak dapat menjawab pertanyaan tentang pengemasan dan unboxing selama wawancara dan tes tertulis. Di bawah ini adalah beberapa pertanyaan wawancara umum terkait pengemasan/unboxing.
1. Apa hasil output dari kode berikut?
Kelas publik utama {public static void main (string [] args) {integer i1 = 100; integer i2 = 100; integer i3 = 200; integer i4 = 200; System.out.println (i1 == i2); System.out.println (i3 == I4);}} Mungkin beberapa teman akan mengatakan bahwa mereka akan menghasilkan salah, atau beberapa teman akan mengatakan bahwa mereka akan menghasilkan benar. Tetapi sebenarnya outputnya adalah:
BENAR
PALSU
Mengapa hasil seperti itu terjadi? Hasil output menunjukkan bahwa I1 dan I2 menunjuk ke objek yang sama, sementara I3 dan I4 menunjuk ke objek yang berbeda. Pada titik ini, Anda hanya perlu melihat kode sumber untuk mengetahui kebenaran. Kode berikut adalah implementasi spesifik dari Metode Nilai Integer:
Nilai integer statis publik (int i) {if (i> = -128 && i <= integercache.high) return integercache.cache [i + 128]; elsereturn integer baru (i);} Implementasi kelas integercache adalah:
Private Static Class Integercache {static final int high; static final integer cache []; static {final int low = -128; // nilai tinggi dapat dikonfigurasi oleh propertiint h = 127; if (integercacheHighpropValue! = null) {// menggunakan long.decode di sini untuk menghindari metode invoking itu/ Long.decode (integercacheHighPropValue) .IntValue (); i = Math.max (i, 127); // Ukuran array maksimum adalah integer.max_valueh = math.min (i, integer.max_value - -low);} tinggi = h; cache = knor = kn = low -low); <cache.length; k ++) cache [k] = integer baru (j ++);} private integercache () {}} Dari dua potong kode ini, saat membuat objek integer melalui metode nilai, jika nilainya antara [-128, 127], referensi ke objek yang sudah ada di integercache.cache dikembalikan; Kalau tidak, objek integer baru dibuat.
Dalam kode di atas, nilai -nilai I1 dan I2 adalah 100, sehingga objek yang ada akan diambil langsung dari cache, jadi I1 dan I2 menunjuk ke objek yang sama, sementara I3 dan I4 menunjuk masing -masing objek yang berbeda.
2. Apa hasil output dari kode berikut?
kelas publik utama {public static void main (string [] args) {double i1 = 100.0; double i2 = 100.0; double i3 = 200.0; double i4 = 200.0; System.out.println (i1 == i2); System.out.println (i3 == I4);}} Mungkin beberapa teman akan berpikir bahwa hasil output sama dengan pertanyaan di atas, tetapi sebenarnya tidak. Output sebenarnya adalah:
PALSU
PALSU
Adapun alasan spesifik, pembaca dapat memeriksa implementasi nilai kelas ganda.
Di sini saya hanya akan menjelaskan mengapa metode nilai dari kelas ganda mengadopsi implementasi yang berbeda dari metode nilai kelas integer. Ini sangat sederhana: jumlah nilai integer dalam kisaran tertentu terbatas, tetapi angka titik mengambang tidak.
Perhatikan bahwa implementasi nilai metode integer, pendek, byte, karakter, dan panjang serupa.
Implementasi nilai metode ganda dan float serupa.
3. Apa hasil output dari kode berikut:
kelas publik utama {public static void main (string [] args) {boolean i1 = false; boolean i2 = false; boolean i3 = true; boolean i4 = true; system.out.println (i1 == i2); System.out.println (i3 == I4);}} Hasil outputnya adalah:
BENAR
BENAR
Adapun mengapa ini hasilnya, Anda juga akan jelas setelah membaca kode sumber kelas Boolean. Berikut ini adalah implementasi spesifik dari Metode Nilai Boolean:
Nilai boolean statis publik (boolean b) {return (b? true: false);} Dan apa yang benar dan salah? 2 Properti anggota statis didefinisikan dalam Boolean:
public static final boolean true = boolean baru (true);/** * <code> boolean </code> objek yang sesuai dengan nilai * nilai primitif <code> false </code>. */public static final boolean false = boolean baru (false);
Pada titik ini, semua orang harus memahami mengapa output di atas benar.
4. Bicara tentang perbedaan antara integer I = integer baru (xxx) dan integer i = xxx;
Tentu saja, topik ini termasuk jenis yang relatif luas. Tetapi poin -poin utama harus dijawab. Izinkan saya meringkas dua perbedaan berikut:
1) metode pertama tidak akan memicu proses tinju otomatis; sedangkan metode kedua akan memicu;
2) Perbedaan dalam efisiensi eksekusi dan pemanfaatan sumber daya. Metode kedua efisiensi eksekusi dan penggunaan sumber daya lebih baik daripada yang pertama secara umum (perhatikan bahwa ini tidak absolut).
5. Apa hasil output dari program berikut?
Kelas publik utama {public static void main (string [] args) {integer a = 1; integer b = 2; integer c = 3; integer d = 3; integer e = 321; integer f = 321; long g = 3l; long h = 2l; System.out.println (c == d); System.out.println (e == f); System.out.println (c == (a+b)); System.out.println (c.equals (a+b)); System.out.println (g == (a+b); out.out.println (g == (a+b); out.out.println (g == (a+b); out.out. Jangan melihat hasil output terlebih dahulu, pembaca akan memikirkan hasil output dari kode ini untuk diri mereka sendiri. Apa yang harus dicatat di sini adalah bahwa ketika dua operan dari operator "==" adalah referensi ke jenis pembungkus, ia membandingkan apakah pointer adalah objek yang sama, dan jika salah satu operan adalah ekspresi (yaitu, berisi operasi aritmatika), ia membandingkan nilai numerik (yang akan memicu proses unboxing otomatis). Selain itu, untuk jenis pembungkus, metode yang sama tidak melakukan konversi tipe. Setelah memahami 2 poin ini, hasil output di atas akan jelas sekilas:
BENAR
PALSU
BENAR
BENAR
BENAR
PALSU
BENAR
Tidak ada keraguan tentang hasil output pertama dan kedua. Dalam kalimat ketiga, karena A+B berisi operasi aritmatika, ia memicu proses unboxing otomatis (metode intvalue akan dipanggil), sehingga mereka membandingkan apakah nilainya sama. Untuk C.Equals (A+B), proses unboxing otomatis akan dipicu terlebih dahulu, dan kemudian proses pengemasan otomatis akan dipicu. Dengan kata lain, A+B, masing -masing akan memanggil metode intvalue, dan setelah mendapatkan nilai setelah operasi penambahan, metode integer.valueof akan dipanggil, dan kemudian perbandingan yang sama akan dilakukan. Hal yang sama berlaku untuk yang berikut, tetapi perhatikan hasil output kedua hingga terakhir dan terakhir (jika nilainya dari tipe int, proses tinju memanggil integer.
Di atas adalah pemahaman yang mendalam tentang pengemasan dan unboxing di Java yang diperkenalkan kepada Anda oleh editor. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!