97. Apakah ada aturan yang berlaku saat mengganti sama dengan()?
Saat mengganti metode sama dengan(), Anda harus mematuhi aturan berikut:-
refleksivitas — untuk nilai apa pun x , x.equals(x) harus selalu menghasilkan nilai true (di mana x != null ).
-
simetri — untuk nilai apa pun x dan y , x.equals(y) harus mengembalikan nilai true hanya jika y.equals(x) mengembalikan true .
-
transitivitas — untuk nilai apa pun x , y dan z , jika x.equals(y) mengembalikan true dan y.equals(z) juga mengembalikan true , maka x.equals(z) harus mengembalikan true .
-
konsistensi — untuk nilai apa pun x dan y , pemanggilan x.equals(y) berulang kali akan selalu mengembalikan nilai yang sama selama bidang yang digunakan untuk membandingkan kedua objek tidak berubah di antara setiap pemanggilan.
-
perbandingan null — untuk nilai apa pun x , pemanggilan x.equals(null) harus menghasilkan false .
98. Apa yang terjadi jika Anda tidak mengganti sama dengan() dan kode hash()?
Dalam hal ini, hashCode() akan mengembalikan nomor yang dihasilkan berdasarkan alamat sel memori tempat objek disimpan. Dengan kata lain, ketika metode hashCode() asli dipanggil pada dua objek dengan bidang yang sama persis, hasilnya akan berbeda (karena keduanya disimpan di lokasi memori yang berbeda). Metode asli sama dengan () membandingkan referensi, yaitu menunjukkan apakah referensi menunjuk ke objek yang sama. Dengan kata lain, perbandingan menggunakan operator == , dan akan selalu menghasilkan false untuk objek yang berbeda, meskipun bidangnya identik. true dikembalikan hanya ketika membandingkan referensi ke objek yang sama. Terkadang masuk akal untuk tidak mengesampingkan metode ini. Misalnya, Anda ingin semua objek dari kelas tertentu menjadi unik — mengganti metode ini hanya akan merusak jaminan kode hash unik yang ada. Hal yang penting adalah memahami nuansa metode-metode ini, baik ditimpa atau tidak, dan menggunakan pendekatan apa pun yang diperlukan dalam situasi tersebut.99. Mengapa persyaratan simetri terpenuhi hanya jika x.equals(y) menghasilkan nilai true?
Pertanyaan ini agak aneh. Jika benda A sama dengan benda B, maka benda B sama dengan benda A. Jika B tidak sama dengan benda A, bagaimana mungkin terjadi sebaliknya? Ini masuk akal.100. Apa yang dimaksud dengan tabrakan HashCode? Bagaimana Anda menghadapinya?
Tabrakan HashCode terjadi ketika dua objek berbeda memiliki HashCode yang sama . Bagaimana mungkin? Nah, kode hash akan dipetakan ke Integer, yang memiliki rentang dari -2147483648 hingga 2147483647. Artinya, ini bisa menjadi salah satu dari sekitar 4 miliar bilangan bulat yang berbeda. Kisaran ini sangat besar namun bukannya tidak terbatas. Itu berarti ada situasi ketika dua objek yang berbeda mungkin memiliki kode hash yang sama. Hal ini sangat kecil kemungkinannya, namun mungkin saja terjadi. Fungsi hash yang diterapkan dengan buruk dapat membuat kode hash yang identik lebih sering muncul dengan mengembalikan angka dalam rentang yang kecil, sehingga meningkatkan kemungkinan tabrakan. Untuk mengurangi tabrakan, Anda perlu menerapkan metode HashCode dengan baik yang menyebarkan nilai secara seragam dan meminimalkan kemungkinan pengulangan nilai.101. Apa yang terjadi jika nilai elemen yang berpartisipasi dalam kontrak kode hash berubah?
Jika elemen yang terlibat dalam perhitungan kode hash berubah, maka kode hash objek harus berubah (jika fungsi hashnya bagus). Itu sebabnya Anda harus menggunakan objek yang tidak dapat diubah sebagai kunci dalam HashMap , karena status internalnya (bidang) tidak dapat diubah setelah pembuatan. Dan selanjutnya kode hash mereka berubah setelah pembuatan. Jika Anda menggunakan objek yang bisa diubah sebagai kunci, maka ketika bidang objek berubah, kode hashnya akan berubah, dan Anda bisa kehilangan pasangan nilai kunci yang sesuai di HashMap . Bagaimanapun, itu akan disimpan di keranjang yang terkait dengan kode hash asli, tetapi setelah objek berubah, Anda akan mencarinya di keranjang lain.102. Tulis metode sama dengan() dan kode hash() untuk kelas Siswa yang memiliki bidang nama String dan usia int.
public class Student {
int age;
String name;
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
final Student student = (Student) o;
if (this.age != student.age) {
return false;
}
return this.name != null ? this.name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = this.age;
result = 31 * result + (this.name != null ? this.name.hashCode() : 0);
return result;
}
}
sama dengan():
-
Pertama, kita bandingkan referensinya secara langsung, karena jika referensinya menunjuk pada objek yang sama, apa gunanya terus mengecek kesetaraannya? Kita sudah tahu bahwa hasilnya akan benar .
-
Kita periksa null dan apakah tipe kelasnya sama karena jika parameternya null atau tipe lain, maka objeknya tidak boleh sama, dan hasilnya harus false .
-
Kami memasukkan parameter ke tipe yang sama (lagipula, bagaimana jika itu adalah objek dari tipe induk).
-
Kami membandingkan bidang primitif (perbandingan menggunakan =! sudah cukup). Jika keduanya tidak sama, kami mengembalikan false .
-
Kami memeriksa bidang non-primitif untuk melihat apakah itu null dan menggunakan metode yang sama ( kelas String menggantikan metode tersebut, sehingga akan melakukan perbandingan dengan benar). Jika kedua bidang bernilai null, atau sama dengan mengembalikan true , kami berhenti memeriksa, dan metode mengembalikan true .
-
Kami menetapkan nilai awal kode hash sama dengan nilai bidang usia objek .
-
Kami mengalikan kode hash saat ini dengan 31 (untuk penyebaran nilai yang lebih besar) dan kemudian menambahkan kode hash dari bidang String non-primitif (jika bukan nol).
-
Kami mengembalikan hasilnya.
-
Mengganti metode dengan cara ini berarti objek dengan nama dan nilai int yang sama akan selalu mengembalikan kode hash yang sama.
103. Apa perbedaan antara menggunakan "if (obj instanceof Student)" dan "if (getClass() == obj.getClass())"?
Mari kita lihat fungsi setiap ekspresi:-
instanceof memeriksa apakah referensi objek di sisi kiri adalah turunan dari tipe di sisi kanan atau salah satu subtipenya.
-
"getClass() == ..." memeriksa apakah tipenya sama.
104. Berikan penjelasan singkat tentang metode clone().
Metode clone () milik kelas Object . Tujuannya adalah untuk membuat dan mengembalikan tiruan (salinan) dari objek saat ini. Untuk menggunakan metode ini, Anda perlu mengimplementasikan antarmuka penanda Cloneable :Student implements Cloneable
Dan ganti metode clone() itu sendiri:
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
Bagaimanapun, ia dilindungi di kelas Object , yaitu hanya akan terlihat di dalam kelas Siswa dan tidak terlihat oleh kelas eksternal.
105. Pertimbangan khusus apa yang perlu Anda ingat mengenai metode clone() dan variabel referensi dalam suatu objek?
Saat objek dikloning, hanya nilai primitif dan nilai referensi objek yang disalin. Artinya, jika suatu objek memiliki bidang yang mereferensikan objek lain, maka hanya referensi tersebut yang akan dikloning — objek referensi lain tersebut tidak akan dikloning. Inilah yang disebut salinan dangkal. Jadi, bagaimana jika Anda memerlukan salinan lengkap, di mana setiap objek yang disarangkan akan dikloning? Bagaimana Anda memastikan bahwa ini bukan sekadar salinan referensi, melainkan salinan lengkap objek berbeda yang menempati alamat memori berbeda di heap? Sebenarnya, semuanya cukup sederhana — untuk setiap kelas yang direferensikan secara internal, Anda perlu mengganti metode clone() dan menambahkan antarmuka penanda Cloneable . Setelah Anda melakukan ini, operasi kloning tidak akan menyalin referensi ke objek yang ada, melainkan menyalin objek yang direferensikan, karena sekarang objek tersebut juga memiliki kemampuan untuk menyalin dirinya sendiri.Pengecualian
106. Apa perbedaan antara kesalahan dan pengecualian?
Pengecualian, serta kesalahan, adalah subkelas dari Throwable . Namun, mereka memiliki perbedaan. Kesalahan tersebut menunjukkan masalah yang terutama terjadi karena kurangnya sumber daya sistem. Dan aplikasi kita seharusnya tidak melihat masalah seperti ini. Contoh kesalahan ini mencakup kerusakan sistem dan kesalahan kehabisan memori. Kesalahan sebagian besar terjadi pada saat runtime, karena tidak dicentang. Pengecualian adalah masalah yang dapat terjadi saat runtime dan waktu kompilasi. Masalah ini biasanya muncul pada kode yang kita tulis sebagai pengembang. Artinya, pengecualian ini lebih dapat diprediksi dan lebih bergantung pada kita. Sebaliknya, kesalahan lebih bersifat acak dan tidak bergantung pada diri kita sendiri. Sebaliknya, mereka bergantung pada masalah pada sistem tempat aplikasi kita berjalan.107. Apa perbedaan antara dicentang, tidak dicentang, pengecualian, lemparan, dan lemparan?
Seperti yang saya katakan sebelumnya, pengecualian adalah kesalahan runtime atau waktu kompilasi yang terjadi pada kode yang ditulis oleh pengembang (karena beberapa situasi tidak normal). Yang dicentang adalah apa yang kita sebut pengecualian yang harus selalu ditangani oleh suatu metode dengan menggunakan mekanisme coba-tangkap atau lemparkan kembali ke metode pemanggil. Kata kunci throws digunakan dalam header metode untuk menunjukkan pengecualian yang mungkin dilontarkan oleh metode tersebut. Dengan kata lain, ini memberi kita mekanisme untuk memberikan pengecualian pada metode pemanggilan. Pengecualian yang tidak dicentang tidak perlu ditangani. Hal ini cenderung kurang dapat diprediksi dan kecil kemungkinannya. Meski begitu, Anda bisa menanganinya jika Anda mau. Kami menggunakan throw ketika melemparkan pengecualian secara manual, misalnya:throw new Exception();
108. Apa yang dimaksud dengan hierarki pengecualian?
Hirarki pengecualian sangat luas. Ada terlalu banyak hal untuk dijelaskan secara memadai di sini. Jadi, kita hanya akan mempertimbangkan cabang utamanya: Di sini, di bagian paling atas hierarki, kita melihat kelas Throwable , yang merupakan nenek moyang umum dari hierarki pengecualian dan kemudian terbagi menjadi:- Kesalahan — masalah kritis yang tidak terkendali.
- Pengecualian — pengecualian yang dapat diperiksa.
109. Apa yang dimaksud dengan pengecualian yang dicentang dan tidak dicentang?
Seperti yang saya katakan sebelumnya:-
Pengecualian yang dicentang adalah pengecualian yang harus Anda tangani. Artinya, Anda harus menanganinya di blok coba-tangkap atau melemparkannya ke metode di atas. Untuk melakukan hal ini, setelah mencantumkan argumen metode dalam tanda tangan metode, gunakan throws <Exception type> untuk menunjukkan bahwa metode dapat memunculkan pengecualian tersebut. Ini seperti peringatan, dengan memberi tahu metode pemanggilan bahwa metode tersebut harus memikul tanggung jawab untuk menangani pengecualian tersebut.
-
Pengecualian yang tidak dicentang tidak perlu ditangani, karena pengecualian tersebut tidak diperiksa pada waktu kompilasi dan biasanya lebih tidak dapat diprediksi. Perbedaan utamanya dengan pengecualian yang dicentang adalah bahwa menanganinya dengan menggunakan blok coba-tangkap atau dengan melempar ulang bersifat opsional dan bukan wajib.
101. Tuliskan contoh di mana Anda menggunakan blok coba-tangkap untuk menangkap dan menangani pengecualian.
try{ // Start of the try-catch block
throw new Exception(); // Manually throw an exception
} catch (Exception e) { // Exceptions of this type and its subtypes will be caught
System.out.println("Oops! Something went wrong =("); // Display the exception
}
102. Tuliskan contoh di mana Anda menangkap dan menangani pengecualian khusus Anda sendiri.
Pertama, mari kita tulis kelas pengecualian kita sendiri yang mewarisi Pengecualian dan ganti konstruktornya yang menggunakan pesan kesalahan sebagai argumen:public class CustomException extends Exception {
public CustomException(final String message) {
super(message);
}
}
Selanjutnya kita akan melemparkan satu secara manual dan menangkapnya seperti yang kita lakukan pada contoh pertanyaan sebelumnya:
try{
throw new CustomException("Oops! Something went wrong =(");
} catch (CustomException e) {
System.out.println(e.getMessage());
}
Sekali lagi, ketika kita menjalankan kode kita, kita mendapatkan output berikut:
GO TO FULL VERSION