Saya baru-baru ini melihat peringatan saya di Eclipse dan menemukan yang ini:
Ini akan memberikan peringatan compiler jika metode dapat dideklarasikan sebagai statis.
[sunting] Kutipan yang tepat dalam bantuan Eclipse, dengan penekanan pada pribadi dan final:
Saat diaktifkan, kompilator akan mengeluarkan kesalahan atau peringatan untuk metode yang bersifat pribadi atau final dan yang merujuk hanya ke anggota statis.
Ya, saya tahu saya bisa mematikannya, tapi saya ingin tahu alasan untuk menyalakannya?
Mengapa sebaiknya mendeklarasikan setiap metode yang mungkin sebagai statis?
Apakah ini akan memberikan keuntungan kinerja? (di domain seluler)
Menunjukkan metode sebagai statis, saya kira menunjukkan bahwa Anda tidak menggunakan variabel instan sehingga dapat dipindahkan ke kelas gaya utils?
Di penghujung hari, haruskah saya menonaktifkan 'abaikan' ini atau haruskah saya memperbaiki 100+ peringatan yang diberikannya kepada saya?
Apakah menurut Anda ini hanya kata kunci tambahan yang mengotori kode, karena kompiler hanya akan menyebariskan metode ini? (jenis seperti Anda tidak mendeklarasikan setiap variabel yang Anda bisa final tetapi Anda bisa ).
sumber
Jawaban:
Setiap kali Anda menulis metode, Anda memenuhi kontrak dalam ruang lingkup tertentu. Semakin sempit cakupannya, semakin kecil kemungkinan Anda menulis bug.
Jika sebuah metode statis, Anda tidak dapat mengakses anggota non-statis; karenanya, cakupan Anda lebih sempit. Jadi, jika Anda tidak membutuhkan dan tidak akan pernah membutuhkan (bahkan dalam subclass) anggota non-statis untuk memenuhi kontrak Anda, mengapa memberikan akses ke bidang ini ke metode Anda? Mendeklarasikan metode
static
dalam kasus ini akan membiarkan compiler memeriksa bahwa Anda tidak menggunakan anggota yang tidak ingin Anda gunakan.Dan terlebih lagi, ini akan membantu orang yang membaca kode Anda memahami sifat kontrak.
Itulah mengapa dianggap baik untuk mendeklarasikan metode
static
ketika itu benar-benar menerapkan kontrak statis.Dalam beberapa kasus, metode Anda hanya berarti sesuatu yang relatif terhadap sebuah instance kelas Anda, dan itu terjadi bahwa implementasinya tidak benar-benar menggunakan bidang atau instance non-statis. Dalam kasus seperti itu, Anda tidak akan menandai metode tersebut
static
.Contoh di mana Anda tidak akan menggunakan
static
kata kunci:sumber
private
metode dapat dideklarasikan statis, maka hampir selalu harus demikian. Untuk tingkat akses lainnya, ada faktor lain yang perlu dipertimbangkan, seperti pengiriman dinamis.object.method()
memilih metode untuk memanggil.Tidak ada konsep dengan pengoptimalan di sini.
Sebuah
static
metode adalahstatic
karena Anda secara eksplisit menyatakan bahwa metode tidak bergantung pada setiap contoh kelas melampirkan hanya karena tidak perlu. Demikian peringatan Eclipse, seperti yang tertera dalam dokumentasi:Jika Anda tidak memerlukan variabel instan dan metode Anda bersifat privat (tidak dapat dipanggil dari luar) atau final (tidak dapat diganti) maka tidak ada alasan untuk membiarkannya menjadi metode normal daripada metode statis. Metode statis secara inheren lebih aman bahkan hanya karena Anda diizinkan untuk melakukan lebih sedikit hal dengannya (tidak memerlukan contoh apa pun, Anda tidak memiliki
this
objek implisit ).sumber
Saya tidak memiliki info tentang kinerjanya, saya kira itu paling sedikit lebih baik, karena kode tidak perlu melakukan pengiriman dinamis berdasarkan tipenya.
Namun, argumen yang jauh lebih kuat terhadap pemfaktoran ulang menjadi metode statis adalah bahwa saat ini menggunakan statis dianggap praktik yang buruk. Metode / variabel statis tidak terintegrasi dengan baik ke dalam bahasa berorientasi objek dan juga, sulit untuk diuji dengan benar. Inilah alasan mengapa beberapa bahasa baru mengabaikan konsep metode / variabel statis sama sekali, atau mencoba untuk menginternalisasikannya ke dalam bahasa dengan cara yang lebih baik dalam OO (mis. Objek di Scala).
Sering kali, Anda memerlukan metode statis untuk mengimplementasikan fungsi yang hanya menggunakan parameter sebagai input dan menghasilkan output menggunakan itu (misalnya fungsi utilitas / pembantu) Dalam bahasa modern, ada konsep Fungsi kelas satu yang memungkinkannya, jadi statis tidak dibutuhkan. Java 8 akan memiliki ekspresi lambda terintegrasi, jadi kita sudah bergerak ke arah ini.
sumber
private static
metode sehingga Anda tidak perlu mengejeknya1. Metode deklarasi
static
memberikan sedikit manfaat kinerja, tetapi yang lebih berguna, ini memungkinkan penggunaan tanpa memiliki instance objek di tangan (pikirkan misalnya tentang metode pabrik atau mendapatkan singleton). Ini juga melayani tujuan dokumentasi untuk menceritakan sifat metode. Tujuan dokumentasi ini tidak boleh diabaikan, karena memberikan petunjuk langsung tentang sifat metode kepada pembaca kode dan pengguna API dan juga berfungsi sebagai alat untuk berpikir bagi programmer asli - menjadi eksplisit tentang makna yang dimaksudkan membantu Anda juga berpikir jernih dan menghasilkan kode kualitas yang lebih baik (menurut saya berdasarkan pengalaman pribadi saya, tetapi orang-orang berbeda). Sebagai contoh, adalah logis dan oleh karena itu diinginkan untuk membedakan antara metode yang beroperasi pada suatu tipe dan metode yang bekerja pada sebuah instance dari tipe tersebut (seperti ditunjukkan olehJon Skeet dalam komentarnya untuk pertanyaan C # ).Namun kasus penggunaan lain untuk
static
metode adalah untuk meniru antarmuka pemrograman prosedural. Pikirkanjava.lang.System.println()
kelas dan metode serta atribut di dalamnya. Kelasjava.lang.System
digunakan seperti ruang nama pengelompokan daripada objek instantiable.2. Bagaimana Eclipse (atau program lain atau jenis - biocomposable atau non-biocomposable - entity) mengetahui dengan pasti metode mana yang dapat dideklarasikan sebagai statis? Bahkan jika kelas dasar tidak mengakses variabel instan atau memanggil metode non-statis, dengan mekanisme pewarisan hal-hal dapat berubah. Hanya jika metode tersebut tidak dapat diganti dengan mewarisi subkelas, kami dapat mengklaim dengan kepastian 100% bahwa metode tersebut benar-benar dapat dideklarasikan
static
. Mengesampingkan metode tidak mungkin dilakukan persis dalam dua kasus keberadaanprivate
(tidak ada subclass yang dapat menggunakannya secara langsung dan bahkan pada prinsipnya tidak mengetahuinya), ataufinal
(meskipun dapat diakses oleh subclass, tidak ada cara untuk mengubah metode untuk merujuk ke data atau fungsi instance).Oleh karena itu logika opsi Eclipse.
3. Poster asli juga bertanya: “ Menunjukkan metode sebagai statis, saya kira menunjukkan bahwa Anda tidak menggunakan variabel instan sehingga dapat dipindahkan ke kelas gaya utils? ” Ini adalah poin yang sangat bagus. Terkadang perubahan desain semacam ini ditunjukkan dengan peringatan.
Ini adalah opsi yang sangat berguna, yang secara pribadi akan saya pastikan untuk diaktifkan, jika saya menggunakan Eclipse dan jika saya memprogram di Java.
sumber
Lihat jawaban Samuel tentang bagaimana ruang lingkup metode berubah. Saya rasa, ini adalah aspek utama dalam membuat metode statis.
Anda juga bertanya tentang kinerja:
Mungkin ada keuntungan performa yang kecil, karena panggilan ke metode statis tidak memerlukan referensi implisit "ini" sebagai parameter.
Namun, dampak kinerja ini sangat kecil. Oleh karena itu, ini semua tentang ruang lingkup.
sumber
Dari pedoman Performa Android:
http://developer.android.com/training/articles/perf-tips.html#PreferStatic
sumber
Dokumentasi Eclipse menjelaskan tentang peringatan yang dimaksud:
Saya pikir itu cukup banyak mengatakan itu semua. Jika metode tersebut bersifat pribadi dan final dan hanya merujuk pada anggota statis, metode yang dimaksud mungkin juga akan dinyatakan statis dan dengan ini, jelaskan bahwa kami hanya bermaksud untuk mengakses konten statis darinya.
Sejujurnya saya tidak berpikir ada alasan misterius lain di baliknya.
sumber
Saya kehilangan beberapa angka untuk perbedaan kecepatan. Jadi saya mencoba untuk melakukan benchmark yang ternyata tidak begitu mudah: Java loop menjadi lebih lambat setelah beberapa run / kesalahan JIT?
Saya akhirnya menggunakan Caliper dan hasilnya sama dengan menjalankan tes saya dengan tangan:
Tidak ada perbedaan terukur untuk panggilan statis / dinamis. Setidaknya tidak untuk Linux / AMD64 / Java7.
Hasil Caliper ada di sini: https://microbenchmarks.appspot.com/runs/1426eac9-36ca-48f0-980f-0106af064e8f#r:scenario.benchmarkSpec.methodName,scenario.vmSpec.options.CMSLargeCoalSurplusPercent,scenari.vm. CMSLargeSplitSurplusPercent, scenario.vmSpec.options.CMSSmallCoalSurplusPercent, scenario.vmSpec.options.CMSSmallSplitSurplusPercent, scenario.vmSpec.options.FLSLargestMarkCoalesceProximity, scenario.vmSpec.options.FLSLargest.vmark
dan hasil saya sendiri adalah:
Kelas Tes Kaliper adalah:
Dan kelas Tes saya sendiri adalah:
sumber
Metode yang dapat Anda deklarasikan sebagai statis adalah metode yang tidak memerlukan pembuatan instance, seperti
Yang kemudian dapat Anda panggil kembali di kelas lain tanpa memberi contoh kelas itu.
... Tapi itu sesuatu yang mungkin sudah Anda ketahui. Itu tidak memberi Anda manfaat nyata apa pun, selain membuatnya lebih jelas bahwa metode tersebut tidak menggunakan variabel instan apa pun.
Dengan kata lain, Anda dapat mematikannya sepenuhnya dengan aman. Jika Anda tahu bahwa Anda tidak akan pernah menggunakan metode di kelas lain (dalam hal ini seharusnya hanya bersifat pribadi), Anda tidak perlu metode itu statis sama sekali.
sumber