Menggunakan pengubah "final" kapan pun berlaku di Java [ditutup]
194
Di Jawa, ada praktik mendeklarasikan setiap variabel (lokal atau kelas), parameter final jika memang benar.
Meskipun ini membuat kode lebih banyak bertele-tele, ini membantu dalam membaca / memahami kode dengan mudah dan juga mencegah kesalahan karena niatnya ditandai dengan jelas.
Apa pendapat Anda tentang ini dan apa yang Anda ikuti?
Ini bisa mengarah pada argumen agama. Beberapa orang menyukainya, beberapa orang membencinya. Saya suka bidang terakhir tetapi bukan variabel lokal final kecuali jika perlu, tidak yakin sepenuhnya rasional. Tidak yakin ada down-vote akan baik. Saya setuju dengan Alex Miller. ;)
Peter Lawrey
Saya bisa mengerti jika orang tidak suka kode mereka berantakan dengan final. Tapi ini adalah masalah yang bisa diselesaikan oleh editor yang baik: bugs.eclipse.org/bugs/show_bug.cgi?id=409379
Saya pikir itu semua ada hubungannya dengan gaya pengkodean yang baik. Tentu saja Anda dapat menulis program yang bagus dan tangguh tanpa menggunakan banyak finalpengubah di mana saja, tetapi ketika Anda memikirkannya ...
Menambah finalsemua hal yang seharusnya tidak berubah hanya mempersempit kemungkinan bahwa Anda (atau programmer berikutnya, mengerjakan kode Anda) akan salah menafsirkan atau menyalahgunakan proses pemikiran yang menghasilkan kode Anda. Setidaknya itu harus membunyikan lonceng ketika mereka sekarang ingin mengubah hal yang sebelumnya tidak dapat diubah.
Pada awalnya, itu terlihat aneh untuk melihat banyak finalkata kunci dalam kode Anda, tetapi segera Anda akan berhenti memperhatikan kata itu sendiri dan hanya akan berpikir, bahwa hal-hal yang tidak akan pernah berubah dari-titik-ini- pada (Anda dapat mengambilnya dari saya ;-)
Saya pikir ini latihan yang bagus. Saya tidak menggunakannya sepanjang waktu, tetapi ketika saya bisa dan masuk akal untuk memberi label sesuatu finalsaya akan melakukannya.
Alih-alih menggunakan kata kunci terakhir untuk parameter, Anda dapat menggunakan alat analisis statis seperti FindBugs untuk meminta variabel parameter tidak dipindahkan. Dengan cara ini Anda menghapus beban sintaksis dan dapat memberlakukannya melalui pemeriksaan FindBugs di alat integrasi Berkelanjutan Anda.
Timo Westkämper
20
@Timo Ini akan berhasil, tetapi memiliki kelemahan yang perlu diperiksa setelah checkin dan tidak saat dev sedang mengerjakan kode. Sebab final, kompiler jelas tidak akan membiarkan Anda melanjutkan jika Anda membuat kesalahan.
Mike
9
Eclipse memiliki opsi untuk menambahkan finalsedapat mungkin (variabel yang tidak berubah) setiap kali Anda menyimpan.
Bert F
22
+1 Saya suka final. Itu tidak membuat perbedaan 98% dari waktu, itu adalah ketidaknyamanan kecil% 1 dari waktu, tetapi 1% dari waktu itu menyelamatkan saya dari melakukan sesuatu yang bodoh atau tidak diinginkan layak dilakukan.
Bert F
14
@BertF Ya, saya selalu membiarkan Eclipse menambahkan finalpengubah di mana-mana ketika saya "Bersihkan ..." kode saya. Di mana-mana berarti bahkan dalam blok catch (), dan seperti yang dikatakan, Anda tidak akan melihat mereka setelah beberapa saat. Tentu saja, jika saya akan membuat bahasa, itu finalakan menjadi default, dan a varatau modifiableakan menjadi kata kunci opsional.
Maarten Bodewes
191
Terobsesi:
Bidang terakhir - Menandai bidang sebagai kekuatan akhir harus ditetapkan pada akhir konstruksi, menjadikan referensi bidang tidak dapat diubah. Ini memungkinkan publikasi bidang yang aman dan dapat menghindari kebutuhan sinkronisasi pada pembacaan selanjutnya. (Perhatikan bahwa untuk referensi objek, hanya referensi bidang yang tidak dapat diubah - hal-hal yang mengacu pada referensi objek masih dapat berubah dan yang memengaruhi immutabilitas.)
Final static field - Meskipun saya menggunakan enums sekarang untuk banyak kasus di mana saya dulu menggunakan final static field.
Pertimbangkan tetapi gunakan dengan bijaksana:
Kelas akhir - Kerangka / desain API adalah satu-satunya kasus di mana saya mempertimbangkannya.
Metode akhir - Pada dasarnya sama dengan kelas akhir. Jika Anda menggunakan pola metode templat seperti hal-hal gila dan menandai akhir, Anda mungkin terlalu mengandalkan warisan dan tidak cukup pada delegasi.
Abaikan kecuali merasa anal:
Parameter metode dan variabel lokal - Saya Jarang melakukan ini sebagian besar karena saya malas dan saya menemukannya mengacaukan kode. Saya akan sepenuhnya mengakui bahwa menandai parameter dan variabel lokal yang tidak akan saya modifikasi adalah "righter". Saya berharap itu adalah default. Tetapi tidak dan saya menemukan kode lebih sulit untuk dipahami dengan final seluruh. Jika saya menggunakan kode orang lain, saya tidak akan menariknya tetapi jika saya menulis kode baru saya tidak akan memasukkannya. Satu pengecualian adalah kasus di mana Anda harus menandai sesuatu yang final sehingga Anda dapat mengakses itu dari dalam kelas batin anonim.
jawaban terbaik namun di beberapa pertanyaan tentang topik terakhir ini
Gabriel Ščerbák
4
Sebagian besar waktu ketika saya melihat variabel lokal tanpa kata akhir di depannya dan itu tidak dapat digunakan di sana itu memberitahu saya bahwa saya mungkin harus mengekstrak beberapa kode dalam metode baru yang mengembalikan nilai yang diinginkan yang akan saya buat final. Kasus-kasus di mana ini tidak berlaku adalah ketika saya menggunakan beberapa aliran atau yang lain yang perlu dicoba.
nyxz
32
Anda benar-benar perlu memahami penggunaan penuh kata kunci terakhir sebelum menggunakannya. Ini dapat berlaku untuk dan memiliki pengaruh yang berbeda pada variabel, bidang, metode, dan kelas
Saya sarankan memeriksa artikel yang ditautkan di bawah ini untuk lebih jelasnya.
The finalpengubah, terutama untuk variabel, merupakan sarana untuk memiliki compiler menegakkan konvensi yang umumnya masuk akal: pastikan variabel (lokal atau misalnya) ditugaskan tepat sekali (tidak lebih tidak kurang). Dengan memastikan variabel ditentukan sebelum digunakan, Anda dapat menghindari kasus umum dari NullPointerException:
finalFileInputStream in;if(test)
in =newFileInputStream("foo.txt");elseSystem.out.println("test failed");
in.read();// Compiler error because variable 'in' might be unassigned
Dengan mencegah variabel ditugaskan lebih dari sekali, Anda mencegah pelingkupan overbroad. Alih-alih ini:
String msg =null;for(int i =0; i <10; i++){
msg ="We are at position "+ i;System.out.println(msg);}
msg =null;
Anda disarankan untuk menggunakan ini:
for(int i =0; i <10; i++){finalString msg ="We are at position "+ i;System.out.println(msg);}
Sebenarnya "Dengan memastikan suatu variabel sudah ditentukan sebelum digunakan, Anda dapat menghindari kasus-kasus NullPointerException yang umum:" ini tidak benar, 'final' tidak membuat perbedaan di sini, kompiler tahu dan mengeluh tentang variabel 'in' yang mungkin null dalam contoh yang diberikan.
nyholku
@nyholku Anda benar, di Jawa variabel lokal harus ditentukan sebelum digunakan, juga tanpa final. Tetapi untuk bidang Anda membutuhkan final. Dalam contoh yang sedikit lebih kompleks di mana "in" adalah variabel instan dari sebuah kelas, dan if / else ada di konstruktor, Anda memerlukan final untuk memberi sinyal masalah. Selain itu, juga untuk variabel lokal ada beberapa nilai dalam IMO akhir, karena itu mencegah programmer ceroboh dari 'memperbaiki' kesalahan kompilasi tentang "dalam" yang mungkin tidak ditugaskan dengan menambahkan "= null" ke deklarasi. Dengan kata lain, variabel terakhir mengurangi penggunaan nol, dalam pengalaman saya.
Bruno De Fraine
20
Saya cukup dogmatis tentang mendeklarasikan setiap variabel yang mungkin final. Ini termasuk parameter metode, variabel lokal, dan jarang, bidang nilai objek. Saya punya tiga alasan utama untuk mendeklarasikan variabel akhir di mana-mana:
Mendeklarasikan Niat: Dengan mendeklarasikan variabel akhir, saya menyatakan bahwa variabel ini dimaksudkan untuk ditulis hanya sekali. Ini petunjuk halus untuk pengembang lain, dan petunjuk besar bagi kompiler.
Menegakkan Variabel Sekali Pakai: Saya percaya pada gagasan bahwa setiap variabel seharusnya hanya memiliki satu tujuan dalam hidup. Dengan memberikan setiap variabel hanya satu tujuan, Anda mengurangi waktu yang diperlukan untuk mencapai tujuan variabel tertentu saat debugging.
Izinkan Pengoptimalan: Saya tahu bahwa kompiler digunakan untuk memiliki trik peningkatan kinerja yang bergantung secara khusus pada ketetapan referensi variabel. Saya suka berpikir beberapa trik kinerja lama ini (atau yang baru) akan digunakan oleh kompiler.
Namun, saya berpikir bahwa kelas dan metode akhir hampir tidak berguna sebagai referensi variabel akhir. Kata finalkunci, ketika digunakan dengan deklarasi ini hanya menyediakan penghalang untuk pengujian otomatis dan penggunaan kode Anda dengan cara yang Anda mungkin tidak pernah diantisipasi.
finalvariabel dan parameter metode tidak berdampak pada kinerja karena tidak dinyatakan dalam bytecode.
Steve Kuo
variabel: = latin: varius> variety> dapat dimodifikasi
dieter
17
Java yang efektif memiliki item yang mengatakan "Mendukung objek yang tidak dapat diubah". Mendeklarasikan field sebagai final membantu Anda mengambil beberapa langkah kecil untuk ini, tetapi tentu saja ada lebih banyak objek yang benar-benar tidak dapat diubah dari itu.
Jika Anda tahu bahwa objek tidak dapat diubah, mereka dapat dibagikan untuk dibaca di antara banyak utas / klien tanpa kekhawatiran sinkronisasi, dan lebih mudah untuk alasan tentang bagaimana program berjalan.
hati-hati - final dan abadi adalah konsep yang sama sekali berbeda. Mudah untuk memiliki objek akhir yang bisa berubah - final adalah tentang referensi, mutabilitas adalah tentang instance objek. Orang akhir olaf = Orang baru (); olaf.setName ("Olaf");
Olaf Kock
1
Tepatnya - objek yang tidak dapat diubah adalah satu hal, referensi yang tidak dapat diubah (yaitu final) adalah sesuatu yang sepenuhnya berbeda.
SCdF
2
Tapi mereka terkait erat karena Anda bisa dengan mendeklarasikan bidang Person.name sebagai final (dan mendeklarasikan final kelas, dan ...) menjadikan objek Person final. Namun itu tidak semudah hanya melakukan "Orang terakhir" ...
Sebastian Ganslandt
Ini juga tidak relevan untuk variabel lokal (parameter adalah lokal). Itu hanya berlaku untuk variabel kelas sehingga hanya sebagian menjawab pertanyaan.
Robin
12
Saya tidak pernah berada dalam situasi di mana memiliki kata kunci terakhir pada suatu variabel telah menghentikan saya dari membuat kesalahan, jadi untuk saat ini saya pikir itu buang-buang waktu.
Kecuali ada alasan nyata untuk melakukan itu (seperti pada Anda ingin membuat titik spesifik tentang variabel yang final) Saya lebih suka tidak melakukannya karena saya merasa itu membuat kode kurang dibaca.
Namun, jika Anda tidak menemukan itu membuat kode lebih sulit untuk dibaca atau lebih lama untuk menulis maka tentu saja lakukanlah.
Sunting: Sebagai klarifikasi (dan upaya untuk memenangkan kembali suara), saya tidak mengatakan jangan tandai konstanta sebagai final, saya katakan jangan lakukan hal-hal seperti:
publicString doSomething(){finalString first = someReallyComplicatedExpressionToGetTheString();finalString second = anotherReallyComplicatedExpressionToGetAnother();return first+second;}
Itu hanya membuat kode (menurut saya) lebih sulit untuk dibaca.
Perlu juga diingat bahwa semua yang dilakukan akhir adalah mencegah Anda menugaskan kembali suatu variabel, itu tidak membuatnya tidak berubah atau semacamnya.
Menghidupkan pernyataan itu: Saya telah berada di banyak situasi di mana tidak menggunakan final(dan objek yang tidak dapat berubah secara umum) memiliki faktor yang berkontribusi signifikan terhadap jumlah dan dampak bug.
Chris Vest
3
Aku semua untuk objek abadi, aku hanya belum pernah dalam situasi di mana menandai objek akhir abadi telah membantuku.
SCdF
2
Saya setuju bahwa kita tidak boleh menggunakan final pada variabel lokal dan parameter metode, itu membuat kode jauh lebih mudah dibaca.
rmaruszewski
@ ChrisVest, mungkin fungsi Anda terlalu lama
Pacerier
8
Final harus selalu digunakan untuk konstanta. Ini bahkan berguna untuk variabel berumur pendek (dalam satu metode tunggal) ketika aturan untuk mendefinisikan variabel rumit.
Kedengarannya seperti salah satu argumen terbesar untuk tidak menggunakan kata kunci terakhir adalah "itu tidak perlu", dan "membuang-buang ruang".
Jika kita mengakui banyak manfaat "final" seperti yang ditunjukkan oleh banyak posting hebat di sini, sementara mengakui itu membutuhkan lebih banyak pengetikan dan spasi, saya berpendapat bahwa Java seharusnya membuat variabel "final" secara default, dan mengharuskan hal-hal ditandai " bisa berubah "jika koder menginginkannya.
Ada ribuan kata bahasa Inggris yang dapat dipilih.
RAY
Ini sempurna. Tidak ada argumen yang menentang finalselain dari "terlalu lama untuk menulis", "membuat kode clumsier". Ada beberapa argumen untuk final. Dan kami dapat menambahkannya secara otomatis di save, jika Anda tidak ingin mengetiknya dengan tangan.
Dmitriy Popov
5
Saya menggunakan finalsemua waktu untuk atribut objek.
Kata finalkunci memiliki semantik visibilitas ketika digunakan pada atribut objek. Pada dasarnya, pengaturan nilai atribut objek akhir terjadi sebelum konstruktor kembali. Ini berarti bahwa selama Anda tidak membiarkan thisreferensi keluar dari konstruktor dan Anda gunakan finaluntuk semua atribut Anda, objek Anda (di bawah Java 5 semantik) dijamin akan dibangun dengan benar, dan karena itu juga tidak dapat diubah maka dapat dipublikasikan dengan aman ke utas lainnya.
Objek yang tidak bisa diubah bukan hanya tentang keamanan benang. Mereka juga membuatnya jauh lebih mudah untuk beralasan tentang transisi negara dalam program Anda, karena ruang dari apa yang dapat diubah adalah sengaja dan, jika digunakan secara konsisten, sepenuhnya terbatas hanya pada hal-hal yang harus diubah.
Terkadang saya juga membuat metode final, tetapi tidak sesering itu. Saya jarang membuat kelas final. Saya biasanya melakukan ini karena saya tidak perlu banyak. Saya biasanya tidak menggunakan banyak warisan. Saya lebih suka menggunakan antarmuka dan komposisi objek sebagai gantinya - ini juga cocok untuk desain yang saya temukan sering lebih mudah untuk diuji. Ketika Anda kode ke antarmuka bukan kelas konkret, maka Anda tidak perlu menggunakan warisan saat Anda menguji, karena, dengan kerangka kerja seperti jMock, jauh lebih mudah untuk membuat objek tiruan dengan antarmuka daripada dengan kelas beton.
Saya kira saya harus membuat sebagian besar kelas saya final, tetapi saya belum masuk ke habbit.
Saya harus membaca banyak kode untuk pekerjaan saya. Variabel variabel instance yang hilang adalah salah satu hal utama yang mengganggu saya dan membuat sulit memahami kode. Untuk uang saya, final pada variabel lokal menyebabkan lebih banyak kekacauan daripada kejelasan. Bahasa seharusnya dirancang untuk menjadikannya default, tetapi kita harus hidup dengan kesalahan. Kadang-kadang berguna terutama dengan loop dan tugas yang pasti dengan pohon if-else, tetapi sebagian besar cenderung menunjukkan metode Anda terlalu rumit.
Mengapa tidak menggunakan alat yang mengurangi kekacauan?
Pacerier
@Pacerier Seperti dalam editor yang salah mengartikan kode?
Tom Hawtin - tackline
3
final jelas harus digunakan pada konstanta, dan untuk menegakkan kekekalan, tetapi ada penggunaan penting lainnya pada metode.
Java yang efektif memiliki seluruh item pada ini (Butir 15) menunjukkan jebakan warisan yang tidak diinginkan. Secara efektif jika Anda tidak merancang dan mendokumentasikan kelas Anda untuk warisan, mewarisi darinya dapat memberikan masalah yang tidak terduga (item tersebut memberikan contoh yang baik). Karena itu rekomendasinya adalah Anda menggunakan final pada kelas dan / atau metode apa pun yang tidak dimaksudkan untuk diwarisi.
Itu mungkin tampak kejam, tetapi masuk akal. Jika Anda menulis perpustakaan kelas untuk digunakan oleh orang lain maka Anda tidak ingin mereka mewarisi dari hal-hal yang tidak dirancang untuk itu - Anda akan mengunci diri Anda ke dalam implementasi kelas tertentu untuk kompatibilitas kembali. Jika Anda membuat kode dalam tim, tidak ada yang dapat menghentikan anggota tim lainnya untuk menghapus final jika mereka benar-benar harus melakukannya. Tetapi kata kunci membuat mereka berpikir tentang apa yang mereka lakukan, dan memperingatkan mereka bahwa kelas yang mereka warisi tidak dirancang untuk itu, jadi mereka harus ekstra hati-hati.
Peringatan lain adalah bahwa banyak orang bingung final berarti bahwa isi dari variabel instan tidak dapat berubah, daripada bahwa referensi tidak dapat berubah.
Bahkan untuk variabel lokal, mengetahui bahwa itu dinyatakan final berarti saya tidak perlu khawatir tentang referensi yang akan diubah nanti. Ini berarti bahwa ketika debugging dan saya melihat variabel itu nanti, saya yakin itu merujuk ke objek yang sama. Itu adalah satu hal yang kurang perlu saya khawatirkan ketika mencari bug. Bonusnya adalah jika 99% variabel dinyatakan final, maka beberapa variabel yang benar-benar variabel lebih baik. Juga, final memungkinkan kompiler menemukan beberapa kesalahan bodoh yang mungkin terjadi jika tidak diperhatikan.
Final saat digunakan dengan variabel-variabel di Java menyediakan pengganti konstanta dalam C ++. Jadi ketika final dan statis digunakan untuk variabel itu menjadi tidak berubah. Pada saat yang sama membuat programmer C ++ yang bermigrasi cukup senang ;-)
Ketika digunakan dengan variabel referensi, itu tidak memungkinkan Anda untuk merujuk kembali objek, meskipun objek dapat dimanipulasi.
Ketika final digunakan dengan metode, itu tidak memungkinkan metode untuk ditunggangi oleh subclass.
Setelah penggunaannya sangat jelas, harus digunakan dengan hati-hati. Ini terutama tergantung pada desain karena menggunakan final pada metode tidak akan membantu polimorfisme.
Satu hanya boleh menggunakannya untuk variabel ketika Anda sangat yakin bahwa nilai variabel akan / tidak boleh diubah. Juga pastikan Anda mengikuti konvensi pengkodean yang didorong oleh SUN.for misalnya: int akhir COLOR_RED = 1; (Huruf besar dipisahkan oleh garis bawah)
Dengan variabel referensi, gunakan hanya ketika kita membutuhkan referensi yang tidak dapat diubah ke objek tertentu.
Mengenai bagian keterbacaan, terjadi bahwa komentar memainkan peran yang sangat penting ketika menggunakan pengubah akhir.
Adakah yang bisa memberi tahu saya mengapa ini tidak dipilih ??? Hanya ingin tahu ..
Mahakuasa
Mungkin karena Anda menyatakan bahwa Anda HANYA harus membuatnya final ketika XYZ. Yang lain menganggap itu praktik yang lebih baik untuk membuat SEMUA yang terakhir menjadi final kecuali ada kebutuhan untuk melakukannya sebaliknya.
Outlaw Programmer
1
Sama sekali bukan pengganti kata kunci C ++ const. -1.
tmj
1
Saya tidak pernah menggunakannya pada variabel lokal, ada sedikit gunanya untuk menambahkan verbosity. Bahkan jika Anda tidak berpikir variabel harus dipindahkan, itu akan membuat sedikit perbedaan bagi orang berikutnya yang mengubah kode yang berpikir sebaliknya, dan karena kode tersebut sedang diubah, tujuan asli apa pun untuk membuatnya final mungkin tidak lagi valid. Jika hanya untuk kejelasan, saya percaya itu gagal karena efek negatif dari verbosity.
Hampir sama berlaku untuk variabel anggota juga, karena mereka memberikan sedikit manfaat, kecuali untuk kasus konstanta.
Ini juga tidak ada hubungannya dengan ketidakberdayaan, karena indikator terbaik dari sesuatu yang abadi adalah bahwa hal itu didokumentasikan seperti itu dan / atau tidak memiliki metode yang dapat mengubah objek (ini, bersama dengan membuat kelas final adalah satu-satunya cara untuk menjamin bahwa itu tidak berubah).
Saya mengatur Eclipse untuk menambahkan final pada semua bidang dan atribut yang tidak dimodifikasi. Ini bekerja sangat baik menggunakan Eclipse "save action" yang menambahkan pengubah akhir ini (antara lain) saat menyimpan file.
Untuk argumen saya pikir mereka tidak diperlukan. Mostley mereka hanya menyakiti keterbacaan. Membuat ulang variabel argumen sangat bodoh sehingga saya harus cukup percaya diri bahwa mereka dapat diperlakukan sebagai konstanta.
Fakta bahwa warna terakhir Eclipse merah memudahkan untuk melihat deklarasi variabel dalam kode yang saya pikir meningkatkan readbillity sebagian besar waktu.
Saya mencoba untuk menegakkan aturan bahwa setiap dan semua variabel harus final, tidak ada alasan yang valid untuk tidak. Jauh lebih mudah untuk menjawab "apa variabel ini?" pertanyaan apakah Anda hanya perlu menemukan initilisasi dan yakinlah bahwa itu dia.
Saya benar-benar agak gugup di sekitar variabel non-final sekarang menjadi beberapa hari. Ini seperti perbedaan antara memiliki pisau yang tergantung di seutas benang di kepala Anda, atau hanya dengan memilikinya Anda laci dapur ...
Variabel terakhir hanyalah cara yang bagus untuk nilai label.
Variabel non-final terikat pada bagian dari beberapa algoritma rawan bug.
Salah satu fitur yang bagus adalah bahwa ketika opsi untuk menggunakan variabel keluar dari pertanyaan untuk algoritma sebagian besar waktu solusi adalah untuk menulis suatu metode sebagai gantinya, yang biasanya meningkatkan kode secara signifikan.
Saya telah mengkode untuk sementara waktu sekarang dan menggunakan final kapan pun saya bisa. Setelah melakukan ini sebentar (untuk variabel, parameter metode, dan atribut kelas), saya dapat mengatakan bahwa 90% (atau lebih) dari variabel saya sebenarnya final. Saya pikir manfaat dari TIDAK memiliki variabel yang dimodifikasi ketika Anda tidak mau (saya melihat itu sebelumnya dan kadang-kadang menyakitkan) membayar untuk mengetik ekstra dan kata kunci "final" tambahan dalam kode Anda.
Yang sedang berkata, jika saya akan merancang suatu bahasa, saya akan membuat setiap variabel final kecuali diubah oleh beberapa kata kunci lainnya.
Saya tidak menggunakan banyak akhir untuk kelas dan metode, pikir. Ini adalah pilihan desain yang kurang lebih rumit, kecuali kelas Anda adalah kelas utilitas (dalam hal ini Anda hanya boleh memiliki satu konstruktor pribadi).
Saya juga menggunakan Collections.unmodifiable ... untuk membuat daftar yang tidak dapat dimodifikasi ketika saya membutuhkannya.
Menggunakan kelas lokal anonim untuk pendengar acara dan itu adalah pola umum di Jawa. Penggunaan kata kunci terakhir yang paling umum adalah memastikan bahwa variabel dalam cakupan dapat diakses oleh pendengar genap.
Namun, jika Anda diharuskan untuk menempatkan banyak pernyataan akhir dalam kode Anda. Itu mungkin petunjuk yang baik bahwa Anda melakukan sesuatu yang salah.
Artikel yang diposting di atas memberikan contoh ini:
publicvoid doSomething(int i,int j){finalint n = i + j;// must be declared finalComparator comp =newComparator(){publicint compare(Object left,Object right){return n;// return copy of a local variable}};}
Saya menggunakannya untuk konstanta di dalam dan di luar metode.
Saya hanya kadang-kadang menggunakannya untuk metode karena saya tidak tahu jika subclass TIDAK ingin mengganti metode yang diberikan (untuk alasan apa pun).
Sejauh kelas, hanya untuk beberapa kelas infrastruktur, sudah saya gunakan kelas akhir.
IntelliJ IDEA memperingatkan Anda jika parameter fungsi ditulis ke dalam suatu fungsi. Jadi, saya sudah berhenti menggunakan final untuk argumen fungsi. Saya tidak melihat mereka di dalam perpustakaan java Runtime juga.
Hmm..diedit di satu tempat..masih dikatakan akhirnya di baris kedua ;-)
Mahakuasa
Mengizinkan orang untuk mengesampingkan nilai adalah satu-satunya sumber kejutan dan bug yang sulit
ditebak
0
Menandai final kelas juga dapat membuat beberapa metode binding terjadi pada waktu kompilasi alih-alih runtime. Pertimbangkan "v2.foo ()" di bawah ini - kompiler tahu bahwa B tidak dapat memiliki subkelas, jadi foo () tidak dapat diganti sehingga implementasi untuk memanggil dikenal pada waktu kompilasi. Jika kelas B TIDAK ditandai sebagai final, maka mungkin tipe aktual v2 adalah beberapa kelas yang memanjang B dan menimpa foo ().
class A {void foo(){//do something}}finalclass B extends A {void foo(){}}classTest{publicvoid t(A v1, B v2){
v1.foo();
v2.foo();}}
Menggunakan final untuk konstanta sangat dianjurkan. Namun, saya tidak akan menggunakannya untuk metode atau kelas (atau setidaknya memikirkannya untuk sementara waktu), karena itu membuat pengujian lebih sulit, jika bukan tidak mungkin. Jika Anda benar-benar harus membuat kelas atau metode final, pastikan kelas ini mengimplementasikan beberapa antarmuka, sehingga Anda dapat memiliki tiruan yang mengimplementasikan antarmuka yang sama.
Jawaban:
Saya pikir itu semua ada hubungannya dengan gaya pengkodean yang baik. Tentu saja Anda dapat menulis program yang bagus dan tangguh tanpa menggunakan banyak
final
pengubah di mana saja, tetapi ketika Anda memikirkannya ...Menambah
final
semua hal yang seharusnya tidak berubah hanya mempersempit kemungkinan bahwa Anda (atau programmer berikutnya, mengerjakan kode Anda) akan salah menafsirkan atau menyalahgunakan proses pemikiran yang menghasilkan kode Anda. Setidaknya itu harus membunyikan lonceng ketika mereka sekarang ingin mengubah hal yang sebelumnya tidak dapat diubah.Pada awalnya, itu terlihat aneh untuk melihat banyak
final
kata kunci dalam kode Anda, tetapi segera Anda akan berhenti memperhatikan kata itu sendiri dan hanya akan berpikir, bahwa hal-hal yang tidak akan pernah berubah dari-titik-ini- pada (Anda dapat mengambilnya dari saya ;-)Saya pikir ini latihan yang bagus. Saya tidak menggunakannya sepanjang waktu, tetapi ketika saya bisa dan masuk akal untuk memberi label sesuatu
final
saya akan melakukannya.sumber
final
, kompiler jelas tidak akan membiarkan Anda melanjutkan jika Anda membuat kesalahan.final
sedapat mungkin (variabel yang tidak berubah) setiap kali Anda menyimpan.final
. Itu tidak membuat perbedaan 98% dari waktu, itu adalah ketidaknyamanan kecil% 1 dari waktu, tetapi 1% dari waktu itu menyelamatkan saya dari melakukan sesuatu yang bodoh atau tidak diinginkan layak dilakukan.final
pengubah di mana-mana ketika saya "Bersihkan ..." kode saya. Di mana-mana berarti bahkan dalam blok catch (), dan seperti yang dikatakan, Anda tidak akan melihat mereka setelah beberapa saat. Tentu saja, jika saya akan membuat bahasa, itufinal
akan menjadi default, dan avar
ataumodifiable
akan menjadi kata kunci opsional.Terobsesi:
Pertimbangkan tetapi gunakan dengan bijaksana:
Abaikan kecuali merasa anal:
sumber
Anda benar-benar perlu memahami penggunaan penuh kata kunci terakhir sebelum menggunakannya. Ini dapat berlaku untuk dan memiliki pengaruh yang berbeda pada variabel, bidang, metode, dan kelas
Saya sarankan memeriksa artikel yang ditautkan di bawah ini untuk lebih jelasnya.
Kata Akhir pada Kata Kunci akhir
sumber
The
final
pengubah, terutama untuk variabel, merupakan sarana untuk memiliki compiler menegakkan konvensi yang umumnya masuk akal: pastikan variabel (lokal atau misalnya) ditugaskan tepat sekali (tidak lebih tidak kurang). Dengan memastikan variabel ditentukan sebelum digunakan, Anda dapat menghindari kasus umum dariNullPointerException
:Dengan mencegah variabel ditugaskan lebih dari sekali, Anda mencegah pelingkupan overbroad. Alih-alih ini:
Anda disarankan untuk menggunakan ini:
Beberapa tautan:
sumber
final
untuk membuat Java lebih berdasarkan ekspresi .Saya cukup dogmatis tentang mendeklarasikan setiap variabel yang mungkin
final
. Ini termasuk parameter metode, variabel lokal, dan jarang, bidang nilai objek. Saya punya tiga alasan utama untuk mendeklarasikan variabel akhir di mana-mana:Namun, saya berpikir bahwa kelas dan metode akhir hampir tidak berguna sebagai referensi variabel akhir. Kata
final
kunci, ketika digunakan dengan deklarasi ini hanya menyediakan penghalang untuk pengujian otomatis dan penggunaan kode Anda dengan cara yang Anda mungkin tidak pernah diantisipasi.sumber
final
variabel dan parameter metode tidak berdampak pada kinerja karena tidak dinyatakan dalam bytecode.Java yang efektif memiliki item yang mengatakan "Mendukung objek yang tidak dapat diubah". Mendeklarasikan field sebagai final membantu Anda mengambil beberapa langkah kecil untuk ini, tetapi tentu saja ada lebih banyak objek yang benar-benar tidak dapat diubah dari itu.
Jika Anda tahu bahwa objek tidak dapat diubah, mereka dapat dibagikan untuk dibaca di antara banyak utas / klien tanpa kekhawatiran sinkronisasi, dan lebih mudah untuk alasan tentang bagaimana program berjalan.
sumber
Saya tidak pernah berada dalam situasi di mana memiliki kata kunci terakhir pada suatu variabel telah menghentikan saya dari membuat kesalahan, jadi untuk saat ini saya pikir itu buang-buang waktu.
Kecuali ada alasan nyata untuk melakukan itu (seperti pada Anda ingin membuat titik spesifik tentang variabel yang final) Saya lebih suka tidak melakukannya karena saya merasa itu membuat kode kurang dibaca.
Namun, jika Anda tidak menemukan itu membuat kode lebih sulit untuk dibaca atau lebih lama untuk menulis maka tentu saja lakukanlah.
Sunting: Sebagai klarifikasi (dan upaya untuk memenangkan kembali suara), saya tidak mengatakan jangan tandai konstanta sebagai final, saya katakan jangan lakukan hal-hal seperti:
Itu hanya membuat kode (menurut saya) lebih sulit untuk dibaca.
Perlu juga diingat bahwa semua yang dilakukan akhir adalah mencegah Anda menugaskan kembali suatu variabel, itu tidak membuatnya tidak berubah atau semacamnya.
sumber
final
(dan objek yang tidak dapat berubah secara umum) memiliki faktor yang berkontribusi signifikan terhadap jumlah dan dampak bug.Final harus selalu digunakan untuk konstanta. Ini bahkan berguna untuk variabel berumur pendek (dalam satu metode tunggal) ketika aturan untuk mendefinisikan variabel rumit.
Sebagai contoh:
sumber
Kedengarannya seperti salah satu argumen terbesar untuk tidak menggunakan kata kunci terakhir adalah "itu tidak perlu", dan "membuang-buang ruang".
Jika kita mengakui banyak manfaat "final" seperti yang ditunjukkan oleh banyak posting hebat di sini, sementara mengakui itu membutuhkan lebih banyak pengetikan dan spasi, saya berpendapat bahwa Java seharusnya membuat variabel "final" secara default, dan mengharuskan hal-hal ditandai " bisa berubah "jika koder menginginkannya.
sumber
final
selain dari "terlalu lama untuk menulis", "membuat kode clumsier". Ada beberapa argumen untukfinal
. Dan kami dapat menambahkannya secara otomatis di save, jika Anda tidak ingin mengetiknya dengan tangan.Saya menggunakan
final
semua waktu untuk atribut objek.Kata
final
kunci memiliki semantik visibilitas ketika digunakan pada atribut objek. Pada dasarnya, pengaturan nilai atribut objek akhir terjadi sebelum konstruktor kembali. Ini berarti bahwa selama Anda tidak membiarkanthis
referensi keluar dari konstruktor dan Anda gunakanfinal
untuk semua atribut Anda, objek Anda (di bawah Java 5 semantik) dijamin akan dibangun dengan benar, dan karena itu juga tidak dapat diubah maka dapat dipublikasikan dengan aman ke utas lainnya.Objek yang tidak bisa diubah bukan hanya tentang keamanan benang. Mereka juga membuatnya jauh lebih mudah untuk beralasan tentang transisi negara dalam program Anda, karena ruang dari apa yang dapat diubah adalah sengaja dan, jika digunakan secara konsisten, sepenuhnya terbatas hanya pada hal-hal yang harus diubah.
Terkadang saya juga membuat metode final, tetapi tidak sesering itu. Saya jarang membuat kelas final. Saya biasanya melakukan ini karena saya tidak perlu banyak. Saya biasanya tidak menggunakan banyak warisan. Saya lebih suka menggunakan antarmuka dan komposisi objek sebagai gantinya - ini juga cocok untuk desain yang saya temukan sering lebih mudah untuk diuji. Ketika Anda kode ke antarmuka bukan kelas konkret, maka Anda tidak perlu menggunakan warisan saat Anda menguji, karena, dengan kerangka kerja seperti jMock, jauh lebih mudah untuk membuat objek tiruan dengan antarmuka daripada dengan kelas beton.
Saya kira saya harus membuat sebagian besar kelas saya final, tetapi saya belum masuk ke habbit.
sumber
Saya harus membaca banyak kode untuk pekerjaan saya. Variabel variabel instance yang hilang adalah salah satu hal utama yang mengganggu saya dan membuat sulit memahami kode. Untuk uang saya, final pada variabel lokal menyebabkan lebih banyak kekacauan daripada kejelasan. Bahasa seharusnya dirancang untuk menjadikannya default, tetapi kita harus hidup dengan kesalahan. Kadang-kadang berguna terutama dengan loop dan tugas yang pasti dengan pohon if-else, tetapi sebagian besar cenderung menunjukkan metode Anda terlalu rumit.
sumber
final jelas harus digunakan pada konstanta, dan untuk menegakkan kekekalan, tetapi ada penggunaan penting lainnya pada metode.
Java yang efektif memiliki seluruh item pada ini (Butir 15) menunjukkan jebakan warisan yang tidak diinginkan. Secara efektif jika Anda tidak merancang dan mendokumentasikan kelas Anda untuk warisan, mewarisi darinya dapat memberikan masalah yang tidak terduga (item tersebut memberikan contoh yang baik). Karena itu rekomendasinya adalah Anda menggunakan final pada kelas dan / atau metode apa pun yang tidak dimaksudkan untuk diwarisi.
Itu mungkin tampak kejam, tetapi masuk akal. Jika Anda menulis perpustakaan kelas untuk digunakan oleh orang lain maka Anda tidak ingin mereka mewarisi dari hal-hal yang tidak dirancang untuk itu - Anda akan mengunci diri Anda ke dalam implementasi kelas tertentu untuk kompatibilitas kembali. Jika Anda membuat kode dalam tim, tidak ada yang dapat menghentikan anggota tim lainnya untuk menghapus final jika mereka benar-benar harus melakukannya. Tetapi kata kunci membuat mereka berpikir tentang apa yang mereka lakukan, dan memperingatkan mereka bahwa kelas yang mereka warisi tidak dirancang untuk itu, jadi mereka harus ekstra hati-hati.
sumber
Peringatan lain adalah bahwa banyak orang bingung final berarti bahwa isi dari variabel instan tidak dapat berubah, daripada bahwa referensi tidak dapat berubah.
sumber
Bahkan untuk variabel lokal, mengetahui bahwa itu dinyatakan final berarti saya tidak perlu khawatir tentang referensi yang akan diubah nanti. Ini berarti bahwa ketika debugging dan saya melihat variabel itu nanti, saya yakin itu merujuk ke objek yang sama. Itu adalah satu hal yang kurang perlu saya khawatirkan ketika mencari bug. Bonusnya adalah jika 99% variabel dinyatakan final, maka beberapa variabel yang benar-benar variabel lebih baik. Juga, final memungkinkan kompiler menemukan beberapa kesalahan bodoh yang mungkin terjadi jika tidak diperhatikan.
sumber
Memilih untuk mengetik
final
untuk setiap parameter dalam setiap metode akan menghasilkan banyak iritasi baik untuk coders dan pembaca kode.Setelah iritasi melampaui beralih ke Scala yang wajar di mana argumen adalah final secara default.
Atau, Anda selalu dapat menggunakan alat penata kode yang akan melakukannya secara otomatis untuk Anda. Semua IDE menerapkannya atau sebagai plugin.
sumber
Final saat digunakan dengan variabel-variabel di Java menyediakan pengganti konstanta dalam C ++. Jadi ketika final dan statis digunakan untuk variabel itu menjadi tidak berubah. Pada saat yang sama membuat programmer C ++ yang bermigrasi cukup senang ;-)
Ketika digunakan dengan variabel referensi, itu tidak memungkinkan Anda untuk merujuk kembali objek, meskipun objek dapat dimanipulasi.
Ketika final digunakan dengan metode, itu tidak memungkinkan metode untuk ditunggangi oleh subclass.
Setelah penggunaannya sangat jelas, harus digunakan dengan hati-hati. Ini terutama tergantung pada desain karena menggunakan final pada metode tidak akan membantu polimorfisme.
Satu hanya boleh menggunakannya untuk variabel ketika Anda sangat yakin bahwa nilai variabel akan / tidak boleh diubah. Juga pastikan Anda mengikuti konvensi pengkodean yang didorong oleh SUN.for misalnya: int akhir COLOR_RED = 1; (Huruf besar dipisahkan oleh garis bawah)
Dengan variabel referensi, gunakan hanya ketika kita membutuhkan referensi yang tidak dapat diubah ke objek tertentu.
Mengenai bagian keterbacaan, terjadi bahwa komentar memainkan peran yang sangat penting ketika menggunakan pengubah akhir.
sumber
Saya tidak pernah menggunakannya pada variabel lokal, ada sedikit gunanya untuk menambahkan verbosity. Bahkan jika Anda tidak berpikir variabel harus dipindahkan, itu akan membuat sedikit perbedaan bagi orang berikutnya yang mengubah kode yang berpikir sebaliknya, dan karena kode tersebut sedang diubah, tujuan asli apa pun untuk membuatnya final mungkin tidak lagi valid. Jika hanya untuk kejelasan, saya percaya itu gagal karena efek negatif dari verbosity.
Hampir sama berlaku untuk variabel anggota juga, karena mereka memberikan sedikit manfaat, kecuali untuk kasus konstanta.
Ini juga tidak ada hubungannya dengan ketidakberdayaan, karena indikator terbaik dari sesuatu yang abadi adalah bahwa hal itu didokumentasikan seperti itu dan / atau tidak memiliki metode yang dapat mengubah objek (ini, bersama dengan membuat kelas final adalah satu-satunya cara untuk menjamin bahwa itu tidak berubah).
Tapi hei, itu hanya pendapat saya :-)
sumber
Saya mengatur Eclipse untuk menambahkan final pada semua bidang dan atribut yang tidak dimodifikasi. Ini bekerja sangat baik menggunakan Eclipse "save action" yang menambahkan pengubah akhir ini (antara lain) saat menyimpan file.
Sangat dianjurkan.
Lihat posting blog saya dari Eclipse Save Actions.
sumber
Untuk argumen saya pikir mereka tidak diperlukan. Mostley mereka hanya menyakiti keterbacaan. Membuat ulang variabel argumen sangat bodoh sehingga saya harus cukup percaya diri bahwa mereka dapat diperlakukan sebagai konstanta.
Fakta bahwa warna terakhir Eclipse merah memudahkan untuk melihat deklarasi variabel dalam kode yang saya pikir meningkatkan readbillity sebagian besar waktu.
Saya mencoba untuk menegakkan aturan bahwa setiap dan semua variabel harus final, tidak ada alasan yang valid untuk tidak. Jauh lebih mudah untuk menjawab "apa variabel ini?" pertanyaan apakah Anda hanya perlu menemukan initilisasi dan yakinlah bahwa itu dia.
Saya benar-benar agak gugup di sekitar variabel non-final sekarang menjadi beberapa hari. Ini seperti perbedaan antara memiliki pisau yang tergantung di seutas benang di kepala Anda, atau hanya dengan memilikinya Anda laci dapur ...
Variabel terakhir hanyalah cara yang bagus untuk nilai label.
Variabel non-final terikat pada bagian dari beberapa algoritma rawan bug.
Salah satu fitur yang bagus adalah bahwa ketika opsi untuk menggunakan variabel keluar dari pertanyaan untuk algoritma sebagian besar waktu solusi adalah untuk menulis suatu metode sebagai gantinya, yang biasanya meningkatkan kode secara signifikan.
sumber
Saya telah mengkode untuk sementara waktu sekarang dan menggunakan final kapan pun saya bisa. Setelah melakukan ini sebentar (untuk variabel, parameter metode, dan atribut kelas), saya dapat mengatakan bahwa 90% (atau lebih) dari variabel saya sebenarnya final. Saya pikir manfaat dari TIDAK memiliki variabel yang dimodifikasi ketika Anda tidak mau (saya melihat itu sebelumnya dan kadang-kadang menyakitkan) membayar untuk mengetik ekstra dan kata kunci "final" tambahan dalam kode Anda.
Yang sedang berkata, jika saya akan merancang suatu bahasa, saya akan membuat setiap variabel final kecuali diubah oleh beberapa kata kunci lainnya.
Saya tidak menggunakan banyak akhir untuk kelas dan metode, pikir. Ini adalah pilihan desain yang kurang lebih rumit, kecuali kelas Anda adalah kelas utilitas (dalam hal ini Anda hanya boleh memiliki satu konstruktor pribadi).
Saya juga menggunakan Collections.unmodifiable ... untuk membuat daftar yang tidak dapat dimodifikasi ketika saya membutuhkannya.
sumber
Menggunakan kelas lokal anonim untuk pendengar acara dan itu adalah pola umum di Jawa. Penggunaan kata kunci terakhir yang paling umum adalah memastikan bahwa variabel dalam cakupan dapat diakses oleh pendengar genap.
Namun, jika Anda diharuskan untuk menempatkan banyak pernyataan akhir dalam kode Anda. Itu mungkin petunjuk yang baik bahwa Anda melakukan sesuatu yang salah.
Artikel yang diposting di atas memberikan contoh ini:
sumber
Saya menggunakannya untuk konstanta di dalam dan di luar metode.
Saya hanya kadang-kadang menggunakannya untuk metode karena saya tidak tahu jika subclass TIDAK ingin mengganti metode yang diberikan (untuk alasan apa pun).
Sejauh kelas, hanya untuk beberapa kelas infrastruktur, sudah saya gunakan kelas akhir.
IntelliJ IDEA memperingatkan Anda jika parameter fungsi ditulis ke dalam suatu fungsi. Jadi, saya sudah berhenti menggunakan final untuk argumen fungsi. Saya tidak melihat mereka di dalam perpustakaan java Runtime juga.
sumber
Saya jarang menggunakan metode atau kelas terakhir karena saya suka membiarkan orang menimpanya.
Kalau tidak, saya hanya menggunakan akhirnya jika itu adalah
public/private static final type SOME_CONSTANT;
sumber
Menandai final kelas juga dapat membuat beberapa metode binding terjadi pada waktu kompilasi alih-alih runtime. Pertimbangkan "v2.foo ()" di bawah ini - kompiler tahu bahwa B tidak dapat memiliki subkelas, jadi foo () tidak dapat diganti sehingga implementasi untuk memanggil dikenal pada waktu kompilasi. Jika kelas B TIDAK ditandai sebagai final, maka mungkin tipe aktual v2 adalah beberapa kelas yang memanjang B dan menimpa foo ().
sumber
Menggunakan final untuk konstanta sangat dianjurkan. Namun, saya tidak akan menggunakannya untuk metode atau kelas (atau setidaknya memikirkannya untuk sementara waktu), karena itu membuat pengujian lebih sulit, jika bukan tidak mungkin. Jika Anda benar-benar harus membuat kelas atau metode final, pastikan kelas ini mengimplementasikan beberapa antarmuka, sehingga Anda dapat memiliki tiruan yang mengimplementasikan antarmuka yang sama.
sumber