Pertama sekali kita perlu tahu bahawa Object类
ialah kelas induk (kelas super/kelas asas) bagi semua kelas dalam Java
Maksudnya, dalam Java
, semua kelas mewarisi daripada Object类
, dengan kata lain, kita boleh menggunakan semua kaedah yang dilaksanakan dalam Object类
secara langsung. Kaedah equals
ialah salah satu daripada banyak kaedah yang dilaksanakan oleh Object类
.
Tangkapan skrin berikut adalah daripada Java11 API
Semua kaedah kelas Objek:
equals
: Ia adalah kaedah dalam Object类
Saya hanya boleh menunjukkan kepada anda jdk
kod sumber kemudian
Pertimbangan lalai ialah sama ada alamat adalah sama (kerana intipati asas pembolehubah jenis rujukan adalah untuk menyimpan alamat objek, rakan dengan pengetahuan C/C++ harus mengetahuinya dengan baik), kaedah ini sering ditindih dalam subkelas, Digunakan untuk menentukan sama ada kandungan objek adalah sama. Contohnya, Integer
dan String
, yang akan anda pelajari secara ringkas kemudian (lihat pelaksanaan kod sumber dalam IDEA)
Bolehkah kita menggunakan kaedah Object类
yang telah equals
kami laksanakan? Mengapakah kita perlu mengatasi kaedah equals
? Ini bergantung pada mekanisme pelaksanaan kaedah Object类
equals
.
Kita dapat melihat dengan jelas bahawa lapisan bawah kaedah Object类
equals
dilaksanakan menggunakan ==, yang bermaksud penggunaannya sama dengan apa yang kita biasanya menggunakan Penggunaan == adalah konsisten apabila membandingkan jenis data asas. Mari kita lihat sintaks ==:
== hanya boleh digunakan untuk membandingkan jenis data asas untuk kesaksamaan, iaitu perbandingan nilai mudah; >
Nota: Jangan mengelirukan C/C++
rujukan dengan rujukan C++ sebenarnya adalah pemalar penunjuk, iaitu,
. Inilah sebabnya mengapa rujukan Java
hanya boleh digunakan sebagai alias untuk pembolehubah. C++
int* const
2.1 Contohnya~C++
untuk perbandingan, ralat akan berlaku, seperti yang kita lihat, kita pasti ingin mendapatkan true
, tetapi hasilnya adalah new
==
> true
false
Keputusan larian:
Pada ketika ini, kita sepatutnya mempunyai idea kasar mengapa kita perlu mengatasi
kaedah apabila membandingkan objek, keranaYang diberikan kepada kita tidak berfungsi~~
3 Analisis kod sumber yang sama:equals
Sebelum menulis semula, mari kita lihat pada definisi dalam Object类
:
Java API
equals melaksanakan kesetaraan pada rujukan objek bukan nol: public boolean equals(Object obj)
,
hendaklah Kembalix
x.equals(x)
Simetri: Untuk sebarang nilai rujukan bukan nol true
dan
mengembalikan x
. y
x.equals(y)
true
y.equals(x)
Transitiviti: Untuk sebarang nilai rujukan bukan nol true
,
x
mengembalikan y
, Kemudian z
sepatutnya kembali x.equals(y)
. true
Ketekalan: Untuk sebarang nilai rujukan bukan nol x
dan y
, berbilang panggilan ke x.equals(y)
sentiasa kembali sama ada true
atau sentiasa kembali false
, dengan syarat objek itu tidak diubahsuai Maklumat equals
yang digunakan dalam perbandingan.
Untuk sebarang nilai rujukan bukan kosong x
, x.equals(null)
hendaklah mengembalikan false
.
Kaedah sama dengan Objek kelas melaksanakan perhubungan kesetaraan yang paling mendiskriminasikan pada objek, iaitu, untuk sebarang nilai rujukan bukan nol x dan y, jika dan hanya jika x dan Kaedah ini mengembalikan benar apabila y merujuk kepada objek yang sama (x == y mempunyai nilai benar).
Nota: Biasanya perlu untuk mengatasi kaedah Kod cincang apabila mengatasi kaedah ini untuk mengekalkan kontrak biasa kaedah hashCode
, yang menyatakan bahawa objek yang sama mesti mempunyai kod cincang yang sama.
Seterusnya, lihat kaedah String类
yang ditindih dalam equals
dan kaedah Integer
yang ditindih dalam kelas equals
:
//String类equals源代码: public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
Penjelasan mudah ialah apabila membandingkan objek yang sama, kembalikan true
terus untuk meningkatkan kecekapan. Apabila objek yang dilalui adalah contoh kelas semasa, pertimbangan selanjutnya dimasukkan A for
gelung melintasi setiap aksara rentetan secara bergilir-gilir dan mengembalikan false
selagi satu aksara berbeza.
Mari kita teruskan melihat Integer
kod sumber kelas equals
:
//Integer类的equals源代码: public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
Integer类
kod sumber equals
adalah lebih mudah, cuma muat naiknya Jika objek yang dimasukkan ialah contoh kelas semasa, pertimbangan selanjutnya akan dibuat: apabila nilainya adalah sama, true
akan dikembalikan, dan jika mereka tidak sama, false
akan dikembalikan.
Berikut ialah demonstrasi praktikal⑧, mengambil Integer类
sebagai contoh:
Jelas sekali, kita tahu bahawa Integer类
menulis semula equals
Kaedah dan adalah jenis rujukan. Apabila == digunakan secara langsung untuk membandingkan pembolehubah jenis rujukan, hasilnya ialah false
, dan apabila equals
digunakan untuk membandingkan pembolehubah jenis rujukan, hasilnya ialah true
. Ini dengan baik menggambarkan keperluan untuk mengatasi kaedah equals
. String类
Sahkan sendiri⑧.
(Mari kita bincangkan kesimpulannya dahulu, getClass()
lebih selamat daripada instanceof
)
Pada ketika ini, pada asasnya kita letakkan equals
Pelbagai kod sumber kaedah telah dianalisis, dan langkah seterusnya ialah melaksanakan kaedah equals
sendiri.
Berikut ialah dua equals
kaedah penulisan semula biasa:
Gunakan instanceof
untuk melaksanakan penulisan semula kaedah equals
Gunakan getClass
untuk melaksanakan kaedah equals
mengatasi
Andaikan terdapat senario ini:
Tulis semula dalam kelas segi empat tepat yang telah dibuat< The Objec
kaedah dalam kelas 🎜>t mengembalikan equals
apabila panjang dan lebar segi empat tepat adalah sama, dan mengatasi kaedah TRUE
untuk memaparkan maklumat panjang dan lebar segi empat tepat. dan menguji kelas. hashCode
package com.test10_04; import java.util.Objects; class Rectangle { private double length; private double wide; public Rectangle() { //空实现 } public Rectangle(double length, double wide) { setLength(length); setWide(wide); } public double getLength() { return length; } public void setLength(double length) { assert length > 0.0 : "您的输入有误,长方形的长不能小于0"; this.length = length; } public double getWide() { return wide; } public void setWide(double wide) { assert wide > 0.0 : "您的输入有误,长方形的宽不能小于0"; this.wide = wide; } public double area() { return this.length * this.wide; } public double circumference() { return 2 * (this.wide + this.length); } public boolean equals(Object obj) { if (this == obj) { //判断一下如果是同一个对象直接返回true,提高效率 return true; } if (obj == null || obj.getClass() != this.getClass()) { //如果传进来的对象为null或者二者为不同类,直接返回false return false; } //也可以以下方法: // if (obj == null || !(obj instanceof Rectangle)) { //如果传进来的对象为null或者二者为不同类,直接返回false // return false; // } Rectangle rectangle = (Rectangle) obj; //向下转型 //比较长宽是否相等,注意:浮点数的比较不能简单地用==,会有精度的误差,用Math.abs或者Double.compare return Double.compare(rectangle.length, length) == 0 && Double.compare(rectangle.wide, wide) == 0; } public int hashCode() { //重写equals的同时也要重写hashCode,因为同一对象的hashCode永远相等 return Objects.hash(length, wide); //调用Objects类,这是Object类的子类 } public String toString() { return "Rectangle{" + "length=" + length + ", wide=" + wide + '}'; } } public class TestDemo { public static void main(String[] args) { Rectangle rectangle1 = new Rectangle(3.0, 2.0); Rectangle rectangle2 = new Rectangle(3.0, 2.0); System.out.println(rectangle1.equals(rectangle2)); System.out.println("rectangle1哈希码:" + rectangle1.hashCode() + "\nrectangle2哈希码:" + rectangle2.hashCode()); System.out.println("toString打印信息:" + rectangle1.toString()); } }
toString
Idea pelaksanaan khusus diterangkan dengan sangat jelas dalam kod Di sini kami menumpukan pada menganalisis kelebihan dan kekurangan dua kaedah pelaksanaan dan : getClass
instanceof
Ringkaskan logik kod:
Mari fokus pada kod ringkas ini//getClass()版本 public class Student { private String name; public void setName(String name) { this.name = name; } @Override public boolean equals(Object object){ if (object == this) return true; // 使用getClass()判断对象是否属于该类 if (object == null || object.getClass() != getClass()) return false; Student student = (Student)object; return name != null && name.equals(student.name); }
membenarkan objek menjadi kelas yang sama atau subkelasnya, jadi kaedah yang sama menjadi kelas induk dan subkelas juga boleh melakukan operasi yang sama Pada masa ini, jika subkelas mentakrifkan semula kaedah yang sama, Maka ia mungkin menjadi objek kelas induk menyamai objek subkelas adalah benar, tetapi objek subkelas menyamai objek kelas induk adalah palsu, seperti yang ditunjukkan di bawah: getClass()
//instanceof版本 public class Student { private String name; public void setName(String name) { this.name = name; } @Override public boolean equals(Object object){ if (object == this) return true; // 通过instanceof来判断对象是否属于类 if (object == null || !(object instanceof Student)) return false; Student student = (Student)object; return name!=null && name.equals(student.name); } }
instanceof
Perhatikan bahawa getClass()
Kedua-dua nilai pulangan adalah , yang selaras dengan jangkaan kami (walaupun kelasnya berbeza, jadi mesti
)false
false
:
instanceof
Keputusan larian: Satu adalah true
dan satu lagi adalah false
Jelas sekali terdapat masalah.
Sebabnya di sini adalah seperti berikut: Sintaks instanceof
adalah seperti ini:
Apabila objek ialah contoh kelas, hasilnya ialah true
. Tetapi satu lagi cirinya ialah jika objek ini adalah contoh subkelasnya, hasilnya juga akan menjadi true
. Ini membawa kepada pepijat di atas. Maksudnya, apabila kedua-dua objek yang dibandingkan mempunyai hubungan ibu bapa-anak, instanceof
boleh menyebabkan masalah. **Rakan-rakan yang perlu belajar lebih lanjut boleh mempelajarinya sendiri, jadi disyorkan untuk menggunakan equals
sebanyak mungkin semasa melaksanakan kaedah penulisan semula getClass
.
perlu mengatasi kaedah equals
sambil mengatasi kaedah hashCode
.
Atas ialah kandungan terperinci Bagaimana untuk mengatasi kaedah yang sama dengan betul di Jawa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!