Peringatan sama / hashCode pada anotasi @Data lombok dengan pewarisan

107

Saya memiliki entitas yang mewarisi dari yang lain. Di sisi lain, saya menggunakan proyek lombok untuk mengurangi kode boilerplate, jadi saya beri @Dataanotasi. Anotasi @Datadengan pewarisan menghasilkan peringatan berikutnya:

Menghasilkan implementasi sama dengan / hashCode tetapi tanpa panggilan ke superclass, meskipun kelas ini tidak memperluas java.lang.Object. Jika ini disengaja, tambahkan @EqualsAndHashCode(callSuper=false)ke tipe Anda.

Apakah sebaiknya menambahkan anotasi @EqualsAndHashCode (callSuper = true)atau @EqualsAndHashCode (callSuper = false)? Jika tidak ditambahkan, yang mana callSuper=falseatau callSuper=true?

Pau
sumber

Jawaban:

127

Nilai defaultnya adalahfalse . Itu yang Anda dapatkan jika Anda tidak menentukannya dan mengabaikan peringatannya.

Ya, disarankan untuk menambahkan @EqualsAndHashCodeanotasi pada @Datakelas beranotasi yang memperluas sesuatu selain Object. Saya tidak dapat memberi tahu Anda jika Anda membutuhkan trueatau false, itu tergantung pada hierarki kelas Anda, dan perlu diperiksa kasus per kasus.

Namun, untuk sebuah proyek atau paket, Anda dapat mengkonfigurasi lombok.configuntuk memanggil metode super jika itu bukan subkelas langsung dari Object.

lombok.equalsAndHashCode.callSuper = call

Lihat dokumentasi sistem konfigurasi tentang cara kerjanya, dan @EqualsEndHashCodedokumentasi untuk kunci konfigurasi yang didukung.

Pengungkapan: Saya adalah pengembang lombok.

Roel Spilker
sumber
Bekerja untuk saya. Namun perlu diingat bahwa plugin delombok untuk mengambil file konfigurasi ini harus ditempatkan di direktori root sumber java, bukan di direktori resource, yaitu di src / main / java dan bukan di src / main / resources
user577736
1
@Roel Saya bertanya-tanya mengapa defaultnya salah. Saya mengharapkan yang sebaliknya. Juga, apakah ada cara yang setara untuk mendapatkan toString () untuk memanggil super secara default? Saya melihat saya bisa melakukan "@ToString (callSuper = true)", tetapi tidak melihat pengaturan konfigurasi seperti itu. Terima kasih.
David Siegal
Apakah penting jika saya menambahkan @EqualsAndHashCode (callSuper = true) sebelum atau sesudah @Data?
Anna Klein
@AnnaKlein pesanan tidak masalah
dan carter
48

@EqualsAndHashCode(callSuper=true) harus menyelesaikan peringatan tersebut.

noscreenname
sumber
1
Ini harus menjadi jawaban yang diterima karena menurut saya saran Roel tidak harus dilakukan "lombok.equalsAndHashCode.callSuper = call" alih-alih keputusan untuk setiap kelas harus dibuat.
Anna Klein
4
@Annain Saya rasa tidak. Sebenarnya jawaban ini harus berupa komentar, tidak ada informasi baru di sini, Anda dapat menemukannya di pertanyaan saya. Aku tahu @EqualsAndHashCodemenyelesaikan peringatan itu.
Pau
Sebenarnya sesuai dengan jawaban yang diterima (dan jawaban saya di bawah), Anda harus memilih antara 'callSuper = true' atau 'callSuper = false' dalam penjelasan.
Adam Wise
31

Pertanyaan asli utamanya adalah:

Apakah sebaiknya menambahkan anotasi @EqualsAndHashCode (callSuper = true) atau @EqualsAndHashCode (callSuper = false)?

Jawaban yang diterima pada dasarnya hanya:

...itu tergantung...

Untuk memperluasnya, dokumentasi di @EqualsAndHashCode memiliki beberapa panduan yang solid untuk dipilih. Terutama ini, IMHO:

Dengan menyetel callSuper ke true, Anda bisa menyertakan metode sama dengan dan hashCode superclass Anda dalam metode yang dihasilkan. Untuk hashCode, hasil super.hashCode () dimasukkan ke dalam algoritma hash, dan forequals, metode yang dihasilkan akan mengembalikan nilai false jika implementasi super menganggapnya tidak sama dengan yang diteruskan dalam objek. Ketahuilah bahwa tidak semua implementasi yang sama menangani situasi ini dengan benar. Namun, implementasi sama yang dihasilkan lombok menangani situasi ini dengan benar, sehingga Anda dapat dengan aman memanggil superclass equals jika juga, memiliki metode sama yang dihasilkan lombok.

Untuk sedikit menyaringnya: Pilih 'callSuper = true' jika Anda mewarisi dari superclass yang tidak memiliki informasi status, atau dirinya sendiri menggunakan anotasi @Data, atau memiliki implementasi sama dengan / hash yang "menangani situasi dengan benar" - yang saya tafsirkan sebagai mengembalikan hash yang tepat dari nilai negara bagian.

Adam Wise
sumber
Saya pikir ini adalah jawaban yang menjelaskan dengan baik bagaimana memilih antara callSuper = false dan callSuper = true.
prageeth
Saya setuju. Penjelasan ini sangat membantu.
Kira Resari
10

Jika Anda ingin membandingkan anggota superclass juga, gunakan @EqualsAndHashCode(callSuper=true). Namun, jika Anda hanya ingin membandingkan bidang di kelas saat ini, Anda dapat menggunakan @EqualsAndHashCode(callSuper=false)yang merupakan opsi default .

Jika Anda menggunakan Delombok -feature Anda dapat melihat bahwa perbedaan adalah bahwa ketika diatur ke truebaris ini ditambahkan ke dihasilkan equals metode if (!super.equals(o)) return false;. Jika Anda memiliki anggota dalam superclass yang harus diperhitungkan saat membandingkan dua objek, maka itu harus disetel ke true untuk membandingkan dengan benar.

EvR2f
sumber