Saya telah menemukan beberapa referensi ( misalnya ) yang menyarankan menggunakan final
sebanyak mungkin dan saya bertanya-tanya seberapa penting itu. Ini terutama dalam konteks parameter metode dan variabel lokal, bukan metode akhir atau kelas. Untuk konstanta, itu sangat masuk akal.
Di satu sisi, kompiler dapat membuat beberapa optimasi dan itu membuat maksud programmer lebih jelas. Di sisi lain, itu menambah kata kerja dan optimisasi mungkin sepele.
Apakah ini sesuatu yang harus saya ingat?
Jawaban:
Terobsesi:
Pertimbangkan tetapi gunakan dengan bijaksana:
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.
Sunting: perhatikan bahwa satu kasus penggunaan di mana variabel lokal akhir sebenarnya sangat berguna seperti yang disebutkan oleh @ adam-gent adalah ketika nilai ditugaskan ke var di
if
/else
cabang.sumber
final
secara default. Anda mungkin tidak melihat manfaatnya kecuali Anda menggunakan IDE Java yang benar-benar modern (yaitu, IDEA).final
kelas / metode. Misalnya, jika metode final menyatakan untuk melemparkan pengecualian yang diperiksa tetapi tidak pernah benar-benar melemparkannya, IDEA akan memberi tahu Anda hal itu, dan Anda dapat menghapus pengecualian darithrows
klausa. Terkadang, Anda juga dapat menemukan seluruh metode yang tidak digunakan, yang dapat dideteksi ketika mereka tidak dapat diganti.Tidak, jika Anda menggunakan Eclipse, karena Anda dapat mengonfigurasi Save Action untuk secara otomatis menambahkan pengubah akhir ini untuk Anda. Maka Anda mendapatkan manfaat dengan sedikit usaha.
sumber
Manfaat waktu pengembangan dari "final" setidaknya sama pentingnya dengan manfaat waktu berjalan. Ini memberi tahu editor masa depan tentang sesuatu tentang niat Anda.
Menandai kelas "final" menunjukkan bahwa Anda tidak melakukan upaya selama desain atau implementasi kelas untuk menangani ekstensi dengan anggun. Jika pembaca dapat membuat perubahan pada kelas, dan ingin menghapus pengubah "final", mereka dapat melakukannya dengan risiko sendiri. Terserah mereka untuk memastikan kelas akan menangani ekstensi dengan baik.
Menandai variabel "final" (dan menugaskannya dalam konstruktor) berguna dengan injeksi dependensi. Ini menunjukkan sifat "kolaborator" dari variabel.
Menandai metode "final" berguna dalam kelas abstrak. Ini jelas menggambarkan di mana titik-titik ekstensi berada.
sumber
Saya menggunakan
final
semua waktu untuk membuat Java lebih berdasarkan ekspresi. Lihat kondisi Java (if,else,switch
) bukan berbasis ekspresi yang selalu saya benci terutama jika Anda terbiasa pemrograman fungsional (yaitu ML, Scala atau Lisp).Jadi Anda harus selalu mencoba (IMHO) menggunakan variabel akhir saat menggunakan kondisi.
Biarkan saya memberi Anda sebuah contoh:
Sekarang Jika tambahkan
case
pernyataan lain dan jangan aturname
kompiler akan gagal. Kompiler juga akan gagal jika Anda tidak memecahkan setiap kasus (bahwa Anda mengatur variabel). Ini memungkinkan Anda untuk membuat Java sangat mirip denganlet
ekspresi Lisp dan membuatnya jadi kode Anda tidak diindentasi secara besar-besaran (karena variabel pelingkupan leksikal).Dan seperti yang dicatat oleh @Recurse (tapi ternyata -1 saya) Anda dapat melakukan sebelumnya tanpa membuat
String name
final
untuk mendapatkan kesalahan kompiler (yang saya tidak pernah bilang Anda tidak bisa) tetapi Anda dapat dengan mudah membuat kesalahan kompiler hilang pengaturan nama setelah saklar pernyataan yang membuang semantik ekspresi atau lupa yang lebih burukbreak
yang Anda tidak dapat menyebabkan kesalahan (terlepas dari apa yang dikatakan @Recurse) tanpa menggunakanfinal
:Karena nama pengaturan bug (selain lupa
break
yang juga bug lain) sekarang saya dapat secara tidak sengaja melakukan ini:Variabel terakhir memaksa evaluasi tunggal nama apa yang seharusnya. Mirip dengan bagaimana suatu fungsi yang memiliki nilai kembali harus selalu mengembalikan nilai (mengabaikan pengecualian) blok saklar nama harus menyelesaikan nama dan dengan demikian terikat pada blok switch yang membuat potongan kode refactoring lebih mudah (yaitu refactor Eclipe: ekstrak metode) .
Di atas dalam OCaml:
The
match ... with ...
mengevaluasi seperti ekspresi fungsi yaitu. Perhatikan bagaimana tampilannya seperti pernyataan pergantian kami.Berikut adalah contoh dalam Skema (Raket atau Ayam):
sumber
else if (...)
menjadiif(...)
dan dengan demikian me-reset variabel. Saya menunjukkan kepadanya bahwa tidak akan pernah terjadi dengan variabel final. Pada dasarnyafinal
memaksa Anda untuk menetapkan variabel sekali dan hanya sekali ... jadi: PSaya telah menemukan metode menandai parameter dan penduduk setempat sebagai
final
berguna sebagai bantuan refactoring ketika metode tersebut adalah berantakan beberapa halaman panjangnya. Taburkanfinal
secara bebas, lihat apa yang "tidak dapat ditetapkan ke variabel akhir" kesalahan kompilasi (atau IDE Anda) muntah, dan Anda mungkin menemukan mengapa variabel yang disebut "data" berakhir nol meskipun beberapa (dari tanggal) komentar bersumpah akan terjadi.Kemudian Anda dapat memperbaiki beberapa kesalahan dengan mengganti variabel yang digunakan kembali dengan variabel baru yang dinyatakan lebih dekat ke titik penggunaan. Kemudian Anda menemukan bahwa Anda dapat membungkus seluruh bagian dari metode ini dalam scoping braces, dan tiba-tiba Anda hanya satu penekanan tombol IDE dari "Extract Method" dan monster Anda menjadi lebih mudah dipahami.
Jika metode Anda belum menjadi bangkai kapal yang tidak dapat dipelihara, saya kira mungkin ada nilai dalam membuat barang jadi final untuk mencegah orang mengubahnya menjadi bangkai kata; tetapi jika ini adalah metode singkat (lihat: tidak dapat dipelihara) maka Anda berisiko menambahkan banyak kata. Secara khusus, tanda tangan fungsi Java cukup sulit untuk masuk ke dalam 80 karakter karena tanpa menambahkan enam lagi per argumen!
sumber
final
sebelumnya setiap parameter.Nah, ini semua tergantung pada gaya Anda ... jika Anda SUKA melihat final ketika Anda tidak akan memodifikasi variabel, maka gunakan itu. Jika Anda TIDAK SUKA melihatnya ... maka tinggalkan saja.
Saya pribadi suka sesedikit mungkin verbositas, jadi saya cenderung menghindari penggunaan kata kunci tambahan yang sebenarnya tidak perlu.
Saya lebih suka bahasa dinamis, jadi mungkin tidak mengherankan saya suka menghindari kata-kata kasar.
Jadi, saya akan mengatakan hanya memilih arah yang Anda condongkan dan ikuti saja (apa pun masalahnya, cobalah untuk konsisten).
Sebagai catatan, saya telah mengerjakan proyek yang menggunakan dan tidak menggunakan pola seperti itu, dan saya tidak melihat perbedaan dalam jumlah bug atau kesalahan ... Saya tidak berpikir itu adalah pola yang akan sangat besar tingkatkan jumlah bug Anda atau apa pun, tetapi sekali lagi itu adalah gaya, dan jika Anda suka menyatakan maksud bahwa Anda tidak akan memodifikasinya, maka silakan dan gunakan.
sumber
Berguna dalam parameter untuk menghindari mengubah nilai parameter secara tidak sengaja dan memperkenalkan bug halus. Saya menggunakan untuk mengabaikan rekomendasi ini tetapi setelah menghabiskan 4 jam. dalam metode yang mengerikan (dengan ratusan baris kode dan fors ganda, jika bersarang dan semua jenis praktik buruk) saya akan merekomendasikan Anda untuk melakukannya.
Tentu saja di dunia yang sempurna ini tidak akan terjadi, tapi .. yah .. kadang-kadang Anda harus mendukung kode orang lain. :(
sumber
Jika Anda menulis aplikasi yang seseorang harus membaca kode setelah, katakanlah, 1 tahun, maka ya, gunakan final pada variabel yang tidak boleh dimodifikasi sepanjang waktu. Dengan melakukan ini, kode Anda akan lebih "mendokumentasikan diri sendiri" dan Anda juga mengurangi kesempatan bagi pengembang lain untuk melakukan hal-hal konyol seperti menggunakan konstanta lokal sebagai variabel temporer lokal.
Jika Anda menulis beberapa kode sekali pakai, maka, nah, jangan repot-repot mengidentifikasi semua konstanta dan membuatnya final.
sumber
Saya akan menggunakan final sebanyak yang saya bisa. Melakukannya akan menandai jika Anda tidak sengaja mengubah bidang. Saya juga mengatur parameter Metode ke final. Melakukannya saya telah menangkap beberapa bug dari kode yang saya ambil ketika mereka mencoba untuk 'mengatur' parameter yang melupakan Java lewat nilai.
sumber
Tidak jelas dari pertanyaan apakah ini jelas, tetapi membuat parameter metode akhir hanya mempengaruhi tubuh metode. Ini TIDAK menyampaikan informasi menarik tentang niat metode kepada penyerang. Objek yang diteruskan masih dapat dimutasi dalam metode (final bukan konstanta), dan ruang lingkup variabel berada dalam metode.
Untuk menjawab pertanyaan Anda yang tepat, saya tidak akan repot-repot membuat instance atau variabel lokal (termasuk parameter metode) final kecuali jika diperlukan kode itu (misalnya variabel direferensikan dari kelas batin), atau untuk memperjelas beberapa logika yang sangat rumit.
Sebagai contoh variabel, saya akan membuat mereka final jika mereka adalah konstanta secara logis.
sumber
Ada banyak kegunaan untuk variabel
final
. Berikut ini beberapa di antaranyaKonstanta Terakhir
Ini dapat digunakan kemudian untuk bagian lain dari kode Anda, atau diakses oleh kelas lain, dengan cara itu jika Anda akan mengubah nilai Anda tidak perlu mengubahnya satu per satu.
Variabel akhir
Di kelas ini, Anda membangun variabel akhir yang mencakup yang menambahkan awalan ke parameter environmentKey. Dalam hal ini, variabel final hanya final dalam lingkup eksekusi, yang berbeda pada setiap eksekusi metode. Setiap kali metode dimasukkan, final direkonstruksi. Segera setelah dibangun, itu tidak dapat diubah selama lingkup eksekusi metode. Ini memungkinkan Anda untuk memperbaiki variabel dalam metode selama durasi metode. Lihat di bawah:
Konstanta Terakhir
Ini sangat berguna ketika Anda memiliki baris kode yang sangat panjang, dan itu akan menghasilkan kesalahan kompiler sehingga Anda tidak menjalankan kesalahan logika / bisnis ketika seseorang secara tidak sengaja mengubah variabel yang tidak boleh diubah.
Koleksi Terakhir
Berbeda halnya ketika kita berbicara tentang Koleksi, Anda perlu menetapkannya sebagai yang tidak dapat dimodifikasi.
jika tidak, jika Anda tidak menetapkannya sebagai tidak dapat dimodifikasi:
Kelas Final dan Metode Final tidak dapat diperpanjang atau ditimpa masing-masing.
SUNTING: UNTUK MENCOBA MASALAH KELAS FINAL TENTANG PENERAPAN:
Ada dua cara untuk membuat kelas menjadi final. Yang pertama adalah menggunakan kata kunci akhir dalam deklarasi kelas:
Cara kedua untuk membuat final kelas adalah mendeklarasikan semua konstruktornya sebagai pribadi:
Menandai itu final akan menyelamatkan Anda dari masalah jika mengetahui bahwa itu adalah final, untuk menunjukkan tampilan pada kelas Tes ini. terlihat publik pada pandangan pertama.
Sayangnya, karena satu-satunya konstruktor kelas adalah privat, tidak mungkin untuk memperpanjang kelas ini. Dalam hal kelas Tes, tidak ada alasan bahwa kelas tersebut harus final. Kelas Tes adalah contoh yang baik tentang bagaimana kelas akhir implisit dapat menyebabkan masalah.
Jadi Anda harus menandainya sebagai final ketika Anda secara implisit membuat final kelas dengan menjadikannya konstruktor pribadi.
sumber
Agak dari trade-off seperti yang Anda sebutkan, tapi saya lebih suka menggunakan sesuatu secara eksplisit daripada penggunaan implisit. Ini akan membantu menghilangkan beberapa ambiguitas bagi pengelola kode di masa mendatang - bahkan jika itu hanya Anda.
sumber
Jika Anda memiliki kelas dalam (anonim), dan metode ini perlu mengakses variabel dari metode yang mengandung, Anda harus memiliki variabel itu sebagai final.
Selain itu, apa yang Anda katakan itu benar.
sumber
Gunakan
final
kata kunci untuk variabel jika Anda menjadikan variabel itu sebagaiimmutable
Dengan mendeklarasikan variabel sebagai final, ini membantu pengembang untuk menyingkirkan kemungkinan masalah modifikasi variabel dalam lingkungan yang sangat banyak-threaded.
Dengan rilis java 8, kami memiliki satu konsep lagi yang disebut "
effectively final variable
". Variabel non-final dapat naik sebagai variabel akhir.variabel lokal yang dirujuk dari ekspresi lambda harus final atau efektif final
Hingga Java 7, Anda tidak dapat menggunakan variabel lokal non-final di dalam kelas anonim, tetapi dari Java 8 Anda bisa
Lihat artikel ini
sumber
Pertama-tama, kata kunci akhir digunakan untuk membuat variabel konstan. Konstan berarti tidak berubah. Sebagai contoh:
Anda akan mendeklarasikan variabel final karena satu sentimeter per inci tidak berubah.
Jika Anda mencoba menimpa nilai akhir, variabelnya adalah apa yang dideklarasikan terlebih dahulu. Sebagai contoh:
Ada kesalahan kompilasi yang kira-kira seperti:
Jika variabel Anda tidak dapat dinyatakan final atau jika Anda tidak ingin menyatakannya final coba ini:
Ini akan mencetak:
sumber