Kapan Anda menggunakan anotasi @Override Java dan mengapa?

498

Apa praktik terbaik untuk menggunakan @Overrideanotasi Java dan mengapa?

Sepertinya akan berlebihan untuk menandai setiap metode yang ditimpa dengan @Overridepenjelasan. Apakah ada situasi pemrograman tertentu yang meminta untuk menggunakan @Overridedan yang lain tidak boleh menggunakan @Override?

Alex B
sumber

Jawaban:

515

Gunakan setiap kali Anda mengganti metode untuk dua manfaat. Lakukan agar Anda dapat memanfaatkan pemeriksaan kompiler untuk memastikan Anda benar-benar mengganti metode ketika Anda berpikir. Dengan cara ini, jika Anda membuat kesalahan umum kesalahan mengeja nama metode atau tidak cocok dengan parameter, Anda akan diperingatkan bahwa metode Anda tidak benar-benar menimpa seperti yang Anda pikirkan. Kedua, ini membuat kode Anda lebih mudah dipahami karena lebih jelas ketika metode ditimpa.

Selain itu, di Java 1.6 Anda dapat menggunakannya untuk menandai ketika suatu metode mengimplementasikan antarmuka untuk manfaat yang sama. Saya pikir akan lebih baik memiliki anotasi yang terpisah (seperti @Implements), tetapi lebih baik daripada tidak sama sekali.

Dave L.
sumber
4
Sepanjang baris yang sama dengan "lebih mudah dimengerti", IDE akan melihat anotasi @Override dan menandai secara visual metode utama dalam editor.
Bob Cross
47
Beberapa IDE akan menandai metode yang diganti yang juga tidak memiliki anotasi @Override.
Jay R.
20
Manfaat lainnya adalah jika kelas induk berubah, kompiler akan memastikan bahwa kelas anak telah diperbarui juga.
David
4
@ Jay R .: Benar. Faktanya, misalnya Eclipse bahkan dapat secara otomatis menambahkan @Override jika hilang.
sleske
32
Jika ada orang lain yang tiba di sini karena perubahan yang tampaknya tidak berdokumen dari 1,5 menjadi 1,6 untuk @Overrides pada metode yang berasal dari antarmuka, bugs.sun.com/bugdatabase/view_bug.do?bug_id=5008260 tampaknya merupakan bug yang sesuai. (Terima kasih telah menunjukkannya, Dave L.!)
Henrik Heimbuerger
110

Saya pikir ini sangat berguna sebagai pengingat waktu kompilasi bahwa maksud dari metode ini adalah untuk menimpa metode induk. Sebagai contoh:

protected boolean displaySensitiveInformation() {
  return false;
}

Anda akan sering melihat sesuatu seperti metode di atas yang menimpa metode di kelas dasar. Ini adalah detail implementasi penting dari kelas ini - kami tidak ingin informasi sensitif ditampilkan.

Misalkan metode ini diubah di kelas induk menjadi

protected boolean displaySensitiveInformation(Context context) {
  return true;
}

Perubahan ini tidak akan menyebabkan kesalahan waktu kompilasi atau peringatan - tetapi itu benar-benar mengubah perilaku subclass yang dimaksud.

Untuk menjawab pertanyaan Anda: Anda harus menggunakan anotasi @Override jika tidak ada metode dengan tanda tangan yang sama dalam superclass mengindikasikan bug.

jon
sumber
46

Ada banyak jawaban bagus di sini, jadi izinkan saya menawarkan cara lain untuk melihatnya ...

Tidak ada yang berlebihan ketika Anda mengkode. Anda tidak perlu mengeluarkan biaya apa pun untuk mengetikkan @ override, tetapi penghematannya bisa sangat besar jika Anda salah mengeja nama metode atau mendapatkan tanda tangan yang sedikit salah.

Pikirkan seperti ini: Pada saat Anda menavigasi di sini dan mengetik posting ini, Anda cukup banyak menggunakan lebih banyak waktu daripada yang akan Anda habiskan untuk mengetik @override selama sisa hidup Anda; tetapi satu kesalahan yang dicegah dapat menghemat waktu Anda.

Java melakukan semua yang dapat dilakukan untuk memastikan Anda tidak membuat kesalahan pada waktu edit / kompilasi, ini adalah cara yang hampir gratis untuk menyelesaikan seluruh kelas kesalahan yang tidak dapat dicegah dengan cara lain di luar pengujian komprehensif.

Bisakah Anda membuat mekanisme yang lebih baik di Jawa untuk memastikan bahwa ketika pengguna bermaksud mengganti metode, ia benar-benar melakukannya?

Efek lain yang rapi adalah bahwa jika Anda tidak memberikan anotasi itu akan memperingatkan Anda pada waktu kompilasi bahwa Anda secara tidak sengaja mengesampingkan metode induk - sesuatu yang bisa signifikan jika Anda tidak bermaksud melakukannya.

Bill K.
sumber
3
"Tidak ada yang berlebihan saat kamu mengkode." Saya setuju dengan hal ini, itulah sebabnya saya merasa kesalahan dinamis (walaupun 100% pekerjaan saya yang dibayar saat ini sedang dalam ruby).
Dan Rosenstark
4
+1: Saya telah, mungkin, 10 bug yang disebabkan oleh kesalahan dalam menimpa - waktu yang diperlukan untuk menemukan salah satu dari mereka dengan mudah akan melebihi waktu untuk mengetik @Override pada setiap salah satu metode utama saya. Selain itu, jika @Override sedikit membebani, Anda mungkin menggunakan warisan secara berlebihan.
Lawrence Dol
7
Satu kelemahan yang sangat nyata adalah Anda membuat kode lebih sulit dibaca dengan mengotori siput. Mungkin ini adalah kesalahan IDE saya, tetapi saya sendiri pernah mengalaminya.
perlakukan mod Anda dengan baik
9
@ phyzome Jika Anda menemukan "Siput" rumit, Anda tidak menggunakan MANA SAJA DEKAT komentar yang cukup. Mereka seharusnya hanya satu baris di atas header metode Anda yang seharusnya sekitar sebesar metode Anda dalam banyak kasus (beberapa baris) untuk menyediakan teks hover dan javadocs yang layak. Saya kira saya mengatakan bahwa masalahnya bukan Siput, ini kebiasaan membaca Anda. Apakah semua tanda kurung dalam kode mengganggu Anda juga?
Bill K
4
Ya, ada terlalu banyak dalam pengkodean: ketika Anda menulis komentar yang hanya beo apa kode jelas.
Semut
22

Saya selalu menggunakan tag. Ini adalah flag waktu kompilasi sederhana untuk menangkap kesalahan kecil yang mungkin saya buat.

Ini akan menangkap hal-hal seperti tostring()bukantoString()

Hal-hal kecil membantu dalam proyek besar.

jjnguy
sumber
18

Menggunakan @Overridepenjelasan bertindak sebagai perlindungan waktu kompilasi terhadap kesalahan pemrograman umum. Ini akan memunculkan kesalahan kompilasi jika Anda memiliki anotasi pada metode yang sebenarnya tidak Anda timpa metode superclass.

Kasus paling umum di mana ini berguna adalah ketika Anda mengubah metode di kelas dasar untuk memiliki daftar parameter yang berbeda. Metode dalam subkelas yang digunakan untuk mengganti metode superclass tidak akan lagi melakukannya karena tanda tangan metode yang diubah. Ini kadang-kadang dapat menyebabkan perilaku aneh dan tak terduga, terutama ketika berhadapan dengan struktur warisan yang kompleks. The @Overridepengamanan penjelasan terhadap hal ini.

toluju
sumber
Jawaban Terbaik. Pendek dan manis. Saya berharap Anda bisa menjelaskan bagaimana "perlindungan" bekerja .... tidak ada yang menjelaskan ini.
Djangofan
Sederhana untuk dijelaskan. Jika Anda membuat kesalahan (baik dengan mengubah antarmuka, kelas abstrak atau subkelas, Anda akan mendapatkan peringatan (seperti di Eclipse) atau kesalahan waktu kompilasi yang memberi tahu Anda bahwa @Override Anda tidak berfungsi. Kesalahan yang sebenarnya pesan akan tergantung pada apa yang diubah, tetapi di Eclipse (misalnya) sangat jelas sangat cepat bahwa ada masalah: Anda akan melihat sedikit garis bawah zigzag, dan sebuah kursor di atas teks yang menyinggung akan memberi tahu Anda apa yang salah. Saya menyebutnya Nilai Baik
Ichiro Furusato
14

Untuk mengambil keuntungan dari pengecekan kompiler, Anda harus selalu menggunakan Abaikan anotasi. Tapi jangan lupa bahwa Java Compiler 1.5 tidak akan mengizinkan anotasi ini ketika mengganti metode antarmuka. Anda bisa menggunakannya untuk mengganti metode kelas (abstrak, atau tidak).

Beberapa IDE, seperti Eclipse, bahkan dikonfigurasikan dengan Java 1.6 runtime atau lebih tinggi, mereka mempertahankan kepatuhan dengan Java 1.5 dan tidak mengizinkan penggunaan @override seperti dijelaskan di atas. Untuk menghindari perilaku itu, Anda harus pergi ke: Properti Proyek -> Java Compiler -> Periksa “Aktifkan Pengaturan Khusus Proyek” -> Pilih “Tingkat Kepatuhan Kompiler” = 6.0, atau lebih tinggi.

Saya suka menggunakan anotasi ini setiap kali saya mengganti metode secara mandiri, jika dasarnya adalah antarmuka, atau kelas.

Ini membantu Anda menghindari beberapa kesalahan umum, seperti ketika Anda berpikir bahwa Anda sedang meng-override event handler dan kemudian Anda melihat tidak ada yang terjadi. Bayangkan Anda ingin menambahkan pendengar acara ke beberapa komponen UI:

someUIComponent.addMouseListener(new MouseAdapter(){
  public void mouseEntered() {
     ...do something...
  }
});

Kode di atas mengkompilasi dan menjalankan, tetapi jika Anda memindahkan mouse ke dalam beberapaUIComponent, kode "do something" akan berjalan, karena sebenarnya Anda tidak mengesampingkan metode dasar mouseEntered(MouseEvent ev). Anda cukup membuat metode tanpa parameter baru mouseEntered(). Alih-alih kode itu, jika Anda telah menggunakan @Overrideanotasi Anda telah melihat kesalahan kompilasi dan Anda tidak membuang waktu untuk berpikir mengapa event handler Anda tidak berjalan.

Donal Fellows
sumber
8

@Override pada implementasi antarmuka tidak konsisten karena tidak ada yang namanya "menimpa antarmuka" di java.

@Override pada implementasi antarmuka tidak berguna karena dalam praktiknya tidak ada bug yang tidak bisa ditangkap oleh kompilasi. Hanya ada satu, skenario jauh dibuat di mana menimpa pelaksana benar-benar melakukan sesuatu: Jika Anda menerapkan antarmuka, dan metode antarmuka REMOVES, Anda akan diberitahu pada waktu kompilasi bahwa Anda harus menghapus implementasi yang tidak digunakan. Perhatikan bahwa jika versi baru antarmuka memiliki metode BARU atau BERUBAH Anda pasti akan mendapatkan kesalahan kompilasi karena Anda tidak menerapkan hal-hal baru.

@Override pada pelaksana antarmuka seharusnya tidak pernah diizinkan di 1.6, dan dengan gerhana sayangnya memilih untuk secara otomatis memasukkan anotasi sebagai perilaku default, kami mendapatkan banyak file sumber berantakan. Saat membaca kode 1.6, Anda tidak dapat melihat dari penjelasan @Override jika suatu metode benar-benar menimpa metode dalam superclass atau hanya mengimplementasikan antarmuka.

Menggunakan @Override ketika benar-benar mengganti metode dalam superclass baik-baik saja.

Sajak
sumber
2
Ada berbagai pendapat tentang hal itu. Lihat stackoverflow.com/questions/212614/… .
sleske
8

Yang terbaik untuk menggunakannya untuk setiap metode yang dimaksudkan sebagai override, dan Java 6+, setiap metode yang dimaksudkan sebagai implementasi antarmuka.

Pertama, ia menangkap kesalahan ejaan seperti " hashcode()" bukannya " hashCode()" pada waktu kompilasi. Mungkin membingungkan untuk men-debug mengapa hasil metode Anda tampaknya tidak cocok dengan kode Anda ketika penyebab sebenarnya adalah bahwa kode Anda tidak pernah dipanggil.

Juga, jika superclass mengubah tanda tangan metode, penggantian tanda tangan yang lebih lama dapat "yatim", ditinggalkan sebagai kode mati yang membingungkan. The @Overridepenjelasan akan membantu Anda mengidentifikasi anak yatim ini sehingga mereka dapat dimodifikasi untuk mencocokkan tanda tangan baru.

erickson
sumber
7

Jika Anda sering menemukan metode utama (non-abstrak), Anda mungkin ingin melihat desain Anda. Ini sangat berguna ketika kompiler tidak akan menangkap kesalahan. Misalnya mencoba menimpa initValue () di ThreadLocal, yang telah saya lakukan.

Menggunakan @Override ketika menerapkan metode antarmuka (fitur 1.6+) tampaknya sedikit berlebihan bagi saya. Jika Anda memiliki banyak metode, beberapa di antaranya menimpa dan beberapa tidak, itu mungkin desain yang buruk lagi (dan editor Anda mungkin akan menunjukkan yang mana jika Anda tidak tahu).

Tom Hawtin - tackline
sumber
2
Sebenarnya, ini juga bagus untuk metode antarmuka yang diganti. Jika saya misalnya menghapus metode lama yang sudah usang dari suatu antarmuka, metode itu juga harus dihapus dari semua kelas pelaksana - mudah dikenali jika mereka menggunakan @override.
Dominik Sandjaja
7

@Override pada antarmuka sebenarnya sangat membantu, karena Anda akan mendapatkan peringatan jika Anda mengubah antarmuka.

Asgeir S. Nilsen
sumber
7

Hal lain yang dilakukannya adalah membuatnya lebih jelas ketika membaca kode bahwa itu mengubah perilaku kelas induk. Daripada dapat membantu dalam debugging.

Juga, dalam buku Joshua Block, Java Efektif (edisi ke-2), item 36 memberikan rincian lebih lanjut tentang manfaat anotasi.

Diastrofisme
sumber
Ya, memang - barang 36 :)
Chris Kimpton
6

Sama sekali tidak masuk akal untuk menggunakan @Override ketika menerapkan metode antarmuka. Tidak ada keuntungan untuk menggunakannya dalam kasus itu - kompiler sudah akan menangkap kesalahan Anda, jadi itu hanya kekacauan yang tidak perlu.

Steve R.
sumber
6
Menggunakan @Overridepada antarmuka akan memaksa Anda untuk memperhatikan ketika metode di antarmuka dihapus.
Alex B
@Alex: Menghapus metode dalam antarmuka adalah perubahan yang melanggar, seperti menambahkannya. Setelah antarmuka diterbitkan, ia secara efektif dikunci kecuali Anda memiliki kendali penuh atas semua kode yang menggunakannya.
Lawrence Dol
6

Setiap kali metode menimpa metode lain, atau metode mengimplementasikan tanda tangan di antarmuka.

The @Overridepenjelasan meyakinkan Anda bahwa Anda lakukan sebenarnya menimpa sesuatu. Tanpa anotasi, Anda berisiko salah mengeja atau perbedaan dalam jenis dan nomor parameter.

Greg Mattes
sumber
1
Anda hanya dapat menggunakannya untuk menandai implementasi antarmuka di Java 1.6
Dave L.
5

Saya menggunakannya setiap waktu. Ini lebih banyak informasi yang dapat saya gunakan untuk dengan cepat mengetahui apa yang terjadi ketika saya meninjau kembali kode dalam setahun dan saya lupa apa yang saya pikirkan pertama kali.

Hank Gay
sumber
5

Praktik terbaik adalah selalu menggunakannya (atau minta IDE untuk mengisinya untuk Anda)

Kegunaan @Override adalah untuk mendeteksi perubahan dalam kelas induk yang belum dilaporkan ke hierarki. Tanpanya, Anda dapat mengubah metode tanda tangan dan lupa mengubah penggantiannya, dengan @Override, kompiler akan menangkapnya untuk Anda.

Jaring pengaman semacam itu selalu baik untuk dimiliki.


sumber
1
Jadi, jika Anda mengubah metode induk, dan Anda tidak menggunakan @Override dalam metode kelas anak, akankah kompilasi mengatakan sesuatu atau tetap diam? Akankah penggunaan "Override" memberi Anda lebih banyak informasi, dan jika demikian, apa?
Djangofan
5

Saya menggunakannya di mana-mana. Pada topik upaya untuk menandai metode, saya membiarkan Eclipse melakukannya untuk saya jadi, itu bukan upaya tambahan.

Saya religius tentang refactoring berkelanjutan .... jadi, saya akan menggunakan setiap hal kecil untuk membuatnya berjalan lebih lancar.

willCode4Beer
sumber
5
  • Hanya digunakan pada deklarasi metode.
  • Menunjukkan bahwa deklarasi metode beranotasi menimpa deklarasi dalam supertype.

Jika digunakan secara konsisten, itu melindungi Anda dari kelas besar bug jahat.

Gunakan @Override anotasi untuk menghindari bug ini: (Temukan bug dalam kode berikut :)

public class Bigram {
    private final char first;
    private final char second;
    public Bigram(char first, char second) {
        this.first  = first;
        this.second = second;
    }
    public boolean equals(Bigram b) {
        return b.first == first && b.second == second;
    }
    public int hashCode() {
        return 31 * first + second;
    }

    public static void main(String[] args) {
        Set<Bigram> s = new HashSet<Bigram>();
        for (int i = 0; i < 10; i++)
            for (char ch = 'a'; ch <= 'z'; ch++)
                s.add(new Bigram(ch, ch));
        System.out.println(s.size());
    }
}

sumber: Java yang efektif

jai
sumber
Saya tidak tahu aturan operator apa yang ada di Jawa, tetapi metode equals Anda berteriak BUUUUUUUUUUUUUG! Saya akan menulis (b.first == first) && (b.second == second), bahkan jika &&memiliki prioritas lebih rendah daripada ==.
pyon
Tahukah Anda bahwa tautan Anda menampilkan pesan 'Anda harus berlangganan' yang mencakup bagian berguna halaman itu?
Adriano Varoli Piazza
@Adriano: Maaf Bung !! Saya tidak berdaya !! Ketika saya menulis 'jawaban', itu tersedia. Jangan khawatir..beli buku. Layak untuk memilikinya !!
jai
5
Metode equals tidak menimpa: Yang asli Object::equalsadalah boolean equals(Object), sedangkan yang ditimpa equalsadalah boolean equals(Bigram), yang memiliki tanda tangan metode yang berbeda, yang tidak menimpa. Menambahkan @Override ke equalsakan mendeteksi kesalahan ini.
Ming-Tang
3

Berhati-hatilah saat menggunakan Override, karena Anda tidak dapat melakukan reverse engineer di starUML sesudahnya; buat uml dulu.

Horatiu Jeflea
sumber
2

Tampaknya kebijaksanaan di sini sedang berubah. Hari ini saya menginstal IntelliJ IDEA 9 dan memperhatikan bahwa " inspeksi @Override hilang " sekarang menangkap tidak hanya menerapkan metode abstrak, tetapi juga menerapkan metode antarmuka. Dalam basis kode majikan saya dan dalam proyek saya sendiri, saya sudah lama memiliki kebiasaan untuk hanya menggunakan @Override untuk metode abstrak yang diterapkan sebelumnya. Namun, memikirkan kembali kebiasaan itu, manfaat menggunakan anotasi dalam kedua kasus menjadi jelas. Meskipun lebih verbose, ia melindungi terhadap masalah kelas dasar yang rapuh (tidak separah contoh yang terkait dengan C ++) di mana nama metode antarmuka berubah, menjadi yatim piatu yang menerapkan metode pelaksana di kelas turunan.

Tentu saja, skenario ini sebagian besar hiperbola; kelas turunan tidak akan lagi dikompilasi, sekarang kurang implementasi dari metode antarmuka berganti nama, dan hari ini orang mungkin akan menggunakan Metode Ganti Nama operasi refactoring untuk mengatasi seluruh basis kode secara massal.

Mengingat bahwa inspeksi IDEA tidak dapat dikonfigurasi untuk mengabaikan metode antarmuka yang diterapkan, hari ini saya akan mengubah kebiasaan saya dan kriteria ulasan kode tim saya.

seh
sumber
2

Anotasi @Override digunakan untuk membantu memeriksa apakah pengembang harus mengganti metode yang benar di kelas induk atau antarmuka. Ketika nama metode super berubah, kompiler dapat memberi tahu kasus itu, yang hanya untuk menjaga konsistensi dengan super dan subkelas.

BTW, jika kita tidak mengumumkan anotasi @Override di subclass, tapi kita menimpa beberapa metode super, maka fungsinya dapat berfungsi seperti itu dengan @Override. Tetapi metode ini tidak dapat memberi tahu pengembang ketika metode super diubah. Karena tidak tahu tujuan pengembang - menimpa metode super atau menentukan metode baru?

Jadi ketika kita ingin mengganti metode itu untuk menggunakan Polymorphism, kita harus menambahkan @Override di atas metode tersebut.

Gaya
sumber
1

Saya menggunakannya sebanyak mungkin untuk mengidentifikasi ketika suatu metode sedang diganti. Jika Anda melihat bahasa pemrograman Scala, mereka juga memiliki kata kunci override. Saya merasakan manfaatnya.

Berlin Brown
sumber
0

Itu memungkinkan Anda (well, kompiler) untuk menangkap ketika Anda telah menggunakan ejaan yang salah pada nama metode yang Anda timpa.

Astaga
sumber
0

Abaikan anotasi digunakan untuk mengambil keuntungan dari kompiler, untuk memeriksa apakah Anda benar-benar mengganti metode dari kelas induk. Ini digunakan untuk memberi tahu jika Anda melakukan kesalahan seperti kesalahan salah mengeja nama metode, kesalahan tidak cocok dengan parameter

Siva
sumber
0

Saya pikir yang terbaik adalah kode @override kapan saja diizinkan. ini membantu untuk coding. Namun, untuk dicatat, untuk ecipse Helios, baik sdk 5 atau 6, penjelasan @override untuk metode antarmuka yang diimplementasikan diperbolehkan. Sedangkan untuk Galileo, baik 5 atau 6, penjelasan override @ tidak diperbolehkan.

lwpro2
sumber
0

Anotasi memberikan data meta tentang kode ke Kompiler dan anotasi @Override digunakan dalam kasus pewarisan ketika kita mengganti metode apa pun dari kelas dasar. Itu hanya memberitahu kompiler bahwa Anda menimpa metode. Ini dapat menghindari beberapa jenis kesalahan umum yang bisa kita lakukan seperti tidak mengikuti tanda tangan yang tepat dari metode atau salah mengeja nama metode dll.

gprathour
sumber
0

Bagi saya @Override memastikan saya bahwa saya memiliki tanda tangan metode yang benar. Jika saya memasukkan anotasi dan metode ini tidak dieja dengan benar, maka kompiler mengeluh membiarkan saya tahu ada sesuatu yang salah.

Lembah
sumber
0

Sederhana – saat Anda ingin mengganti metode yang ada dalam superclass Anda, gunakan @Overrideanotasi untuk membuat penggantian yang benar. Kompiler akan memperingatkan Anda jika Anda tidak menimpanya dengan benar.

Sree
sumber