Bagaimana untuk mengatasi kaedah yang sama dengan betul di Jawa
1. Apakah kaedah yang sama?
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:
1.1 sama dengan Kaedah:
equals
: Ia adalah kaedah dalamObject类
Saya hanya boleh menunjukkan kepada andajdk
kod sumber kemudianPertimbangan 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
danString
, yang akan anda pelajari secara ringkas kemudian (lihat pelaksanaan kod sumber dalam IDEA)
2. Mengapakah kita perlu menulis semula kaedah sama?
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; >
== Mungkin juga terdapat kegagalan semasa membandingkan nombor titik terapung Ini kerana mekanisme penyimpanan nombor titik terapung adalah berbeza daripada keluarga integer Nombor titik terapung itu sendiri tidak boleh mewakili nilai yang tepat (. anda boleh menyemak sendiri sebab-sebab tertentu peraturan IEEE 754, tidak akan dikembangkan di sini) - Jadi kita boleh gunakan == apabila hanya membandingkan nilai jenis data asas, tetapi kita tidak boleh lakukan ini apabila membandingkan jenis data rujukan, seperti yang dinyatakan di atas Telah disebutkan bahawa jenis data rujukan pada dasarnya digunakan untuk merujuk/menyimpan alamat objek, jadi anda boleh menganggapnya sebagai penunjuk
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++
dan apabila
kedua-dua atribut itu betul-betul. yang sama. Apabila menggunakan 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~~
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 Kembali- .
-
,x
x.equals(x)
Simetri: Untuk sebarang nilai rujukan bukan noltrue
dan hendaklah mengembalikan - jika dan hanya jika
mengembalikan
danx
.y
x.equals(y)
true
y.equals(x)
Transitiviti: Untuk sebarang nilai rujukan bukan noltrue
, , jika - mengembalikan
x
mengembalikany
, Kemudianz
sepatutnya kembalix.equals(y)
.true
Ketekalan: Untuk sebarang nilai rujukan bukan nol
x
dany
, berbilang panggilan kex.equals(y)
sentiasa kembali sama adatrue
atau sentiasa kembalifalse
, dengan syarat objek itu tidak diubahsuai Maklumatequals
yang digunakan dalam perbandingan.Untuk sebarang nilai rujukan bukan kosong
x
,x.equals(null)
hendaklah mengembalikanfalse
.
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⑧.
4. Tulis semula kaedah yang sama dengan betul:
(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 kaedahequals
-
Gunakan
getClass
untuk melaksanakan kaedahequals
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:
//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); }
Malah, kedua-dua penyelesaian adalah sah, perbezaannya ialah mengehadkan objek kepada hanya kelas yang sama , tetapi
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!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas





Panduan Nombor Sempurna di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor Perfect dalam Java?, contoh dengan pelaksanaan kod.

Panduan untuk Weka di Jawa. Di sini kita membincangkan Pengenalan, cara menggunakan weka java, jenis platform, dan kelebihan dengan contoh.

Panduan untuk Nombor Smith di Jawa. Di sini kita membincangkan Definisi, Bagaimana untuk menyemak nombor smith di Jawa? contoh dengan pelaksanaan kod.

Dalam artikel ini, kami telah menyimpan Soalan Temuduga Spring Java yang paling banyak ditanya dengan jawapan terperinci mereka. Supaya anda boleh memecahkan temuduga.

Java 8 memperkenalkan API Stream, menyediakan cara yang kuat dan ekspresif untuk memproses koleksi data. Walau bagaimanapun, soalan biasa apabila menggunakan aliran adalah: bagaimana untuk memecahkan atau kembali dari operasi foreach? Gelung tradisional membolehkan gangguan awal atau pulangan, tetapi kaedah Foreach Stream tidak menyokong secara langsung kaedah ini. Artikel ini akan menerangkan sebab -sebab dan meneroka kaedah alternatif untuk melaksanakan penamatan pramatang dalam sistem pemprosesan aliran. Bacaan Lanjut: Penambahbaikan API Java Stream Memahami aliran aliran Kaedah Foreach adalah operasi terminal yang melakukan satu operasi pada setiap elemen dalam aliran. Niat reka bentuknya adalah

Panduan untuk TimeStamp to Date di Java. Di sini kita juga membincangkan pengenalan dan cara menukar cap waktu kepada tarikh dalam java bersama-sama dengan contoh.

Kapsul adalah angka geometri tiga dimensi, terdiri daripada silinder dan hemisfera di kedua-dua hujungnya. Jumlah kapsul boleh dikira dengan menambahkan isipadu silinder dan jumlah hemisfera di kedua -dua hujungnya. Tutorial ini akan membincangkan cara mengira jumlah kapsul yang diberikan dalam Java menggunakan kaedah yang berbeza. Formula volum kapsul Formula untuk jumlah kapsul adalah seperti berikut: Kelantangan kapsul = isipadu isipadu silinder Dua jumlah hemisfera dalam, R: Radius hemisfera. H: Ketinggian silinder (tidak termasuk hemisfera). Contoh 1 masukkan Jejari = 5 unit Ketinggian = 10 unit Output Jilid = 1570.8 Unit padu menjelaskan Kirakan kelantangan menggunakan formula: Kelantangan = π × r2 × h (4

Java ialah bahasa pengaturcaraan popular yang boleh dipelajari oleh pembangun pemula dan berpengalaman. Tutorial ini bermula dengan konsep asas dan diteruskan melalui topik lanjutan. Selepas memasang Kit Pembangunan Java, anda boleh berlatih pengaturcaraan dengan mencipta program "Hello, World!" Selepas anda memahami kod, gunakan gesaan arahan untuk menyusun dan menjalankan program, dan "Hello, World!" Pembelajaran Java memulakan perjalanan pengaturcaraan anda, dan apabila penguasaan anda semakin mendalam, anda boleh mencipta aplikasi yang lebih kompleks.
