Java: kapan harus menggunakan metode statis

911

Saya bertanya-tanya kapan harus menggunakan metode statis? Katakanlah jika saya memiliki kelas dengan beberapa getter dan setter, satu atau dua metode, dan saya ingin metode-metode itu hanya tidak dapat disangkal pada objek instance kelas. Apakah ini berarti saya harus menggunakan metode statis?

misalnya

Obj x = new Obj();
x.someMethod

atau

Obj.someMethod

(Apakah ini cara statis?)

Saya agak bingung!

KP65
sumber

Jawaban:

1458

Satu aturan dasar: tanyakan pada diri sendiri "Apakah masuk akal untuk memanggil metode ini, bahkan jika belum ada objek yang dibangun?" Jika demikian, itu pasti statis.

Jadi di kelas CarAnda mungkin memiliki metode:

double convertMpgToKpl(double mpg)

... yang akan menjadi statis, karena orang mungkin ingin tahu apa konversi 35mpg, bahkan jika tidak ada yang pernah membangun Car. Tetapi metode ini (yang menetapkan efisiensi satu Car):

void setMileage(double mpg)

... tidak bisa statis karena tidak dapat memanggil metode sebelum ada yang Cardibangun.

(Omong-omong, kebalikannya tidak selalu benar: Anda mungkin kadang-kadang memiliki metode yang melibatkan dua Carobjek, dan masih ingin itu menjadi statis. Misalnya:

Car theMoreEfficientOf( Car c1, Car c2 )

Meskipun ini dapat dikonversi ke versi non-statis, beberapa orang akan berpendapat bahwa karena tidak ada pilihan "istimewa" yang Carlebih penting, Anda tidak boleh memaksa penelepon untuk memilih satu Carsebagai objek yang Anda akan memanggil metode aktif. Namun, situasi ini menyumbang sebagian kecil dari semua metode statis.)

bukan-just-yeti
sumber
325
Beberapa contoh bagus di sini. Saya akan menambahkan, bagaimanapun, bahwa "statis" sering berharga ketika Anda tahu ada sesuatu yang tidak akan berubah di seluruh contoh. Jika ini masalahnya, saya akan benar-benar mempertimbangkan "Prinsip Responsabilitas Tunggal", yang menyiratkan kelas harus memiliki satu responsabilitas dan dengan demikian hanya satu alasan untuk berubah. Saya merasa orang harus mempertimbangkan untuk memindahkan fungsi "ConvertMpgToKpl (mpg ganda)", dan metode serupa, ke kelas mereka sendiri. Tujuan dari objek mobil adalah untuk memungkinkan Instansiasi mobil, tidak memberikan perbandingan di antara mereka. Itu harus eksternal untuk kelas.
Zack Jannsen
34
Saya pikir saya lebih suka metodenya Car#isMoreEfficientThan(Car). Ini memiliki keuntungan bahwa mobil mana yang Anda kembalikan tidak tidak sembarangan. Jelas dengan judul metode apa yang dikembalikan dalam dasi.
Cruncher
5
Saya juga akan berhati-hati tentang membuat metode statis yang menggunakan beberapa sumber daya eksternal (filesystem, database, dll) jenis statis ini dapat membuatnya mengerikan untuk menguji metode yang dikonsumsi. Saya pribadi mencoba mempertahankan statika di ranah "utilitas".
Seth M.
7
Bahkan, itu harus diimplementasikan sebagai pembanding .
Dogweather
3
@ B1KMusic Tentu saja. Yang saya maksud dengan "mobil mana yang dikembalikan dengan dasi" adalah "peta yang benar untuk mobil yang dipanggil, dan peta yang salah untuk mobil yang lewat". Itu tanpa ambiguitas.
Cruncher
538

Tetapkan metode statis hanya dalam skenario berikut:

  1. Jika Anda menulis kelas utilitas dan mereka tidak seharusnya diubah.
  2. Jika metode ini tidak menggunakan variabel instan.
  3. Jika operasi apa pun tidak bergantung pada pembuatan instance.
  4. Jika ada beberapa kode yang dapat dengan mudah dibagikan dengan semua metode instance, ekstrak kode itu menjadi metode statis.
  5. Jika Anda yakin bahwa definisi metode tidak akan pernah diubah atau diganti. Karena metode statis tidak dapat diganti.
Mohd
sumber
45
poin yang baik, tetapi mereka persyaratan jika Anda ingin membuat metode statis, bukan alasan untuk membuatnya.
tetsuo
4
@ Mohd tentang persyaratan 5: Kapan Anda bisa 100% yakin metode tidak akan pernah diubah atau diganti? Tidak selalu ada faktor tidak dikenal yang tidak dapat Anda perhitungkan saat Anda menulis metode statis Anda?
PixelPlex
8
"Kelas Utilitas" sangat sulit untuk dipikirkan, hal buruknya adalah cepat atau lambat semuanya mulai 'terlihat seperti' utilitas (ya saya maksudkan paket "util" yang membengkak, tidak tersentuh dan diuji dengan buruk), dan test case Anda akan membutuhkan lebih banyak pekerjaan (untuk mengejek utilitas statis adalah KERAS). Lebih suka objek dulu.
Sergio
2
@ Mohd jawaban ini persis apa yang saya cari. Saya menghadapi banyak masalah menggunakan metode statis dalam multithreading. Bisakah Anda jelaskan poin 2, 3 lebih banyak (dengan contoh 100 jempol untuk Anda)
Prakash Pandey
Saya pikir "kelas statis" harus ditemukan jika Anda akan menggunakan variabel dan metode statis.
Robert Rocha
182

Ada beberapa alasan yang valid untuk menggunakan metode statis:

  • Kinerja : jika Anda ingin beberapa kode dijalankan, dan tidak ingin membuat instance objek tambahan untuk melakukannya, masukkan menjadi metode statis. JVM juga dapat mengoptimalkan metode statis banyak (saya pikir saya pernah membaca James Gosling menyatakan bahwa Anda tidak memerlukan instruksi khusus di JVM, karena metode statis akan sama cepatnya, tetapi tidak dapat menemukan sumbernya - dengan demikian itu bisa sepenuhnya salah). Ya, ini adalah mikro-optimasi, dan mungkin tidak dibutuhkan. Dan kita programmer tidak pernah melakukan hal-hal yang tidak dibutuhkan hanya karena mereka keren, bukan?

  • Kepraktisan : alih-alih menelepon new Util().method(arg), menelepon Util.method(arg), atau method(arg)dengan impor statis. Lebih mudah, lebih pendek.

  • Menambahkan metode : Anda benar-benar ingin String kelas memiliki removeSpecialChars()metode contoh, tetapi tidak ada di sana (dan seharusnya tidak, karena karakter khusus proyek Anda mungkin berbeda dari proyek lain), dan Anda tidak dapat menambahkannya (karena Java agak waras), jadi Anda membuat kelas utilitas, dan panggil removeSpecialChars(s)alih-alih s.removeSpecialChars(). Manis.

  • Kemurnian : mengambil beberapa tindakan pencegahan, metode statis Anda akan menjadi fungsi murni , yaitu, satu-satunya hal yang tergantung pada parameternya. Data masuk, data keluar. Ini lebih mudah dibaca dan di-debug, karena Anda tidak perlu kuatir tentang pewarisan. Anda dapat melakukannya dengan metode instance juga, tetapi kompiler akan membantu Anda sedikit lebih banyak dengan metode statis (dengan tidak mengizinkan referensi ke atribut instance, metode utama, dll.).

Anda juga harus membuat metode statis jika Anda ingin membuat singleton, tetapi ... jangan. Maksudku, pikirkan dua kali.

Sekarang, yang lebih penting, mengapa Anda tidak ingin membuat metode statis? Pada dasarnya, polimorfisme keluar dari jendela . Anda tidak akan bisa menimpa metode, atau mendeklarasikannya dalam antarmuka (pra-Java 8) . Dibutuhkan banyak fleksibilitas dari desain Anda. Juga, jika Anda perlu menyatakan , Anda akan berakhir dengan banyak bug konkurensi dan / atau kemacetan jika Anda tidak berhati-hati.

tetsuo
sumber
1
Banyak alasan bagus yang tercantum di sini tentang kapan statis dapat bermanfaat. Satu lagi yang bisa saya pikirkan adalah bahwa menulis unit test untuk metode seperti itu hanya sederhana
nilesh
@tetuo Terima kasih! Penjelasan Anda sangat jelas dan alasan yang diberikan sangat logis dan masuk akal.
Deniss M.
3
Dan kita programmer tidak pernah melakukan hal-hal yang tidak dibutuhkan hanya karena mereka keren, bukan? +1
Scaramouche
Yang mengatakan metode statis menjadi fungsi bernama penuh stackoverflow.com/questions/155609/…
Ivanzinho
Saya setuju dengan Kinerja dan Kepraktisan, tetapi tidak Kemurnian. Metode statis dapat memodifikasi anggota statis kelas (yang mungkin pribadi). Ini bisa bermanfaat. Misalnya, Anda dapat memiliki metode seperti "static disinkronkan mengalokasikan ID () {return idNext ++;}". Bahkan, metode statis bisa sama murni atau tidak murni sebagai metode non-statis dalam hal efek samping.
Adam Gawne-Cain
42

Setelah membaca artikel Misko saya percaya bahwa metode statis buruk dari sudut pandang pengujian. Anda seharusnya memiliki pabrik (mungkin menggunakan alat injeksi ketergantungan seperti Guice ).

bagaimana cara memastikan bahwa saya hanya punya satu saja

hanya memiliki satu dari masalah. Masalah "bagaimana saya memastikan bahwa saya hanya memiliki satu dari sesuatu" dengan baik terhindar. Anda hanya instantiate satu ApplicationFactory di utama Anda, dan sebagai hasilnya, Anda hanya instantiate satu instance dari semua lajang Anda.

Masalah mendasar dengan metode statis adalah mereka adalah kode prosedural

Masalah mendasar dengan metode statis adalah mereka adalah kode prosedural. Saya tidak tahu bagaimana cara menguji kode prosedur. Unit-testing mengasumsikan bahwa saya dapat instantiate sebagian aplikasi saya secara terpisah Selama instantiasi saya mengirim dependensi dengan mengejek / persahabatan yang menggantikan dependensi nyata. Dengan pemrograman prosedural tidak ada yang bisa "ditransfer" karena tidak ada objek, kode dan data terpisah.

Alfred
sumber
20
Saya tidak mengerti bagian tentang tidak bisa menguji kode prosedural. Tidakkah Anda hanya mengatur kasus uji yang memetakan input yang benar untuk mengoreksi output menggunakan metode statis bersama dengan kelas sebagai "unit" Anda?
tjb
2
Anda dapat melakukannya untuk menguji fungsi-fungsi tersebut. Tetapi ketika menggunakan metode statis ini di kelas lain yang ingin Anda uji, saya percaya Anda tidak dapat memalsukan mereka (mengejek / teman) atau apa pun, karena Anda tidak dapat membuat instance kelas.
Alfred
4
@Alfred: Silakan lihat PowerMock yang memiliki kemampuan untuk mengejek metode statis. Menggunakan PowerMock ada beberapa skenario, jika ada, di mana Anda menemukan dependensi metode yang tidak dapat diejek.
Carles Sala
7
Anda dapat menguji statika unit menggunakan PowerMock, namun Anda akan segera menemukan Anda kehabisan ruang Permgen (melakukan itu, mendapatkan T-shirt), dan itu masih jahat. Kecuali Anda TAHU (berdasarkan setidaknya satu dekade pengalaman Anda sendiri dalam bahasa OO sejati, tidak bermigrasi dari C) maka JANGAN MELAKUKANNYA. Serius, kode terburuk yang pernah saya lihat berasal dari penggunaan statika pengembang tertanam dan dalam kebanyakan kasus kami terjebak dengan itu, selamanya, dan menambahkan lebih banyak kode hanya mengunci kami ke monolith yang tidak dapat dimodifikasi bahkan lebih ketat. Kopling longgar: tidak, dapat diuji: nyaris, dapat dimodifikasi: TIDAK PERNAH. Menghindari!
user1016765
14
Saya dapat memahami kesulitan menguji metode statis yang bergantung pada keadaan statis. Tetapi ketika Anda menguji metode statis stateless seperti Math.abs()atau Arrays.sort(), bahkan metode Anda dapat meneruskan semua dependensi , saya tidak melihat bagaimana hal itu akan menghambat pengujian unit. Saya akan mengatakan aturan sederhana adalah: jika Anda pernah memiliki alasan untuk mengejek logika prosedural, maka jangan memasukkannya dalam metode statis. Saya tidak pernah punya alasan untuk mengejek Arrays.sort()atau Math.abs().
Andy
36

Sebuah staticmetode adalah salah satu jenis metode yang tidak perlu objek apapun diinisialisasi untuk itu harus disebut. Pernahkah Anda perhatikan staticdigunakan dalammain fungsi di Jawa? Eksekusi program dimulai dari sana tanpa objek dibuat.

Perhatikan contoh berikut:

 class Languages 
 {
     public static void main(String[] args) 
     {
         display();
     }

     static void display() 
     {
         System.out.println("Java is my favorite programming language.");
     }
  }
Zishan
sumber
jawaban terbaik sebenarnya
Yahya
20

Metode statis di java milik kelas (bukan turunan dari itu). Mereka tidak menggunakan variabel instan dan biasanya akan mengambil input dari parameter, melakukan tindakan di atasnya, lalu mengembalikan beberapa hasil. Metode instance dikaitkan dengan objek dan, seperti namanya, dapat menggunakan variabel instan.

Kevin Sylvestre
sumber
12

Tidak, metode statis tidak terkait dengan sebuah instance; mereka termasuk kelas. Metode statis adalah contoh kedua Anda; metode instance adalah yang pertama.

Duffymo
sumber
1
Anda harus menggunakan metode statis jika tidak memerlukan manipulasi keadaan objek.
MastAvalons
11

Jika Anda menerapkan kata kunci statis dengan metode apa pun, itu dikenal sebagai metode statis.

  1. Metode statis milik kelas daripada objek kelas.
  2. Metode statis dipanggil tanpa perlu membuat instance kelas.
  3. metode statis dapat mengakses anggota data statis dan dapat mengubah nilai itu.
  4. Metode statis dapat diakses hanya menggunakan nama nama statis kelas dot. . . contoh: Student9.change ();
  5. Jika Anda ingin menggunakan bidang non-statis kelas, Anda harus menggunakan metode non-statis.

// Program untuk mengubah properti umum semua objek (bidang statis).

class Student9{  
 int rollno;  
 String name;  
 static String college = "ITS";  

 static void change(){  
 college = "BBDIT";  
 }  

 Student9(int r, String n){  
 rollno = r;  
 name = n;  
 }  

 void display (){System.out.println(rollno+" "+name+" "+college);}  

public static void main(String args[]){  
Student9.change();  

Student9 s1 = new Student9 (111,"Indian");  
Student9 s2 = new Student9 (222,"American");  
Student9 s3 = new Student9 (333,"China");  

s1.display();  
s2.display();  
s3.display();  
}  }

O / P: 111 India BBDIT 222 Amerika BBDIT 333 Cina BBDIT

IndianProgrammer1234
sumber
10

Metode statis tidak terkait dengan turunan, sehingga mereka tidak dapat mengakses bidang non-statis di kelas.

Anda akan menggunakan metode statis jika metode ini tidak menggunakan bidang apa pun (atau hanya bidang statis) dari suatu kelas.

Jika bidang non-statis suatu kelas digunakan, Anda harus menggunakan metode non-statis.

Carsten
sumber
1
Jawaban yang jelas, singkat dan sederhana.
Josi
8

Metode statis harus dipanggil di Kelas, Metode Instans harus dipanggil pada Instans Kelas. Tetapi apa artinya itu dalam kenyataan? Ini adalah contoh yang bermanfaat:

Kelas mobil mungkin memiliki metode instan yang disebut Mempercepat (). Anda hanya dapat Mempercepat mobil, jika mobil itu benar-benar ada (telah dibangun) dan karenanya ini akan menjadi metode instan.

Kelas mobil mungkin juga memiliki metode penghitungan yang disebut GetCarCount (). Ini akan mengembalikan jumlah total mobil yang dibuat (atau dibuat). Jika tidak ada mobil yang dibangun, metode ini akan mengembalikan 0, tetapi harus tetap dapat dipanggil, dan karena itu harus menjadi metode statis.

Charlie Seligman
sumber
6

Sebenarnya, kami menggunakan properti dan metode statis di kelas, ketika kami ingin menggunakan beberapa bagian dari program kami, harus ada di sana sampai program kami berjalan. Dan kita tahu bahwa, untuk memanipulasi properti statis, kita memerlukan metode statis karena mereka bukan bagian dari variabel instan. Dan tanpa metode statis, untuk memanipulasi properti statis membutuhkan waktu.

Sagar
sumber
Mempertahankan status dalam variabel statis adalah hal yang buruk untuk dilakukan karena berbagai alasan - seperti keamanan multi-threading, debugging, enkapsulasi data, dll. Metode statis OK jika mereka adalah fungsi murni (hanya bekerja dengan params, tanpa mengubahnya). Contoh yang bagus adalah kelas utilitas, misalnya perhitungan matematika.
Vladimir Demirev
5

Gunakan metode statis ketika Anda ingin dapat mengakses metode tanpa turunan dari kelas.

Jamey
sumber
29
Ini tidak memberikan alasan untuk desain program.
adamjmarkham
4

Statis: Obj.someMethod

Gunakan staticketika Anda ingin memberikan akses tingkat kelas ke suatu metode, yaitu di mana metode harus dapat dipanggil tanpa turunan dari kelas.

Finbarr
sumber
4

Metode statis tidak perlu dipanggil pada objek dan saat itulah Anda menggunakannya. Contoh: Main () Anda adalah statis dan Anda tidak membuat objek untuk menyebutnya.

Vaishak Suresh
sumber
1
Yay! Lihat di mana saya datang saat mencari pertanyaan Java noobie di Google! Ini dunia kecil :-)
Deepak
1
@Deepak dunia kecil memang :)
Vaishak Suresh
4

Metode dan variabel statis adalah versi terkontrol dari fungsi dan variabel 'Global' di Jawa. Di mana metode dapat diakses sebagai classname.methodName()atauclassInstanceName.methodName() , yaitu metode dan variabel statis dapat diakses menggunakan nama kelas serta instance dari kelas.

Kelas tidak dapat dinyatakan sebagai statis (karena tidak masuk akal. Jika kelas dinyatakan publik, itu dapat diakses dari mana saja), kelas dalam dapat dinyatakan statis.

Manju Yadav
sumber
3

Metode statis dapat digunakan jika

  • Seseorang tidak ingin melakukan tindakan atas contoh (metode utilitas)

    Seperti disebutkan dalam beberapa jawaban di atas dalam posting ini, mengubah mil ke kilometer, atau menghitung suhu dari Fahrenheit ke Celsius dan sebaliknya. Dengan contoh-contoh ini menggunakan metode statis, tidak perlu instantiate objek baru dalam memori tumpukan. Pertimbangkan di bawah ini

    1. new ABCClass(double farenheit).convertFarenheitToCelcium() 
    2. ABCClass.convertFarenheitToCelcium(double farenheit)

    yang pertama menciptakan jejak kelas baru untuk setiap metode yang dipanggil, Kinerja, Praktis . Contohnya adalah kelas StringUtils perpustakaan Matematika dan Apache-Commons di bawah ini:

    Math.random()
    Math.sqrt(double)
    Math.min(int, int)
    StringUtils.isEmpty(String)
    StringUtils.isBlank(String)
  • Seseorang ingin menggunakan fungsi sederhana. Input secara eksplisit diteruskan, dan mendapatkan data hasil sebagai nilai balik. Inheritence, objek instanciation tidak muncul dalam gambar. Ringkas, Dapat Dibaca .

CATATAN : Beberapa orang menentang pengujian metode statis, tetapi metode statis juga dapat diuji! Dengan jMockit, seseorang dapat mengejek metode statis. Testabilitas . Contoh di bawah ini:

new MockUp<ClassName>() {
    @Mock
    public int doSomething(Input input1, Input input2){
        return returnValue;
    }
};
Amit Kaneria
sumber
3

Metode statis adalah metode di Jawa yang dapat dipanggil tanpa membuat objek kelas. Itu milik kelas.

Kami menggunakan metode statis ketika kami tidak perlu menggunakan metode instance.

ruam
sumber
2

Saya bertanya-tanya kapan harus menggunakan metode statis?

  1. Penggunaan umum untuk staticmetode adalah untuk mengakses staticbidang.
  2. Tetapi Anda dapat memiliki staticmetode, tanpa referensi staticvariabel. Metode pembantu tanpa merujuk staticvariabel dapat ditemukan di beberapa kelas java seperti java.lang.Math

    public static int min(int a, int b) {
        return (a <= b) ? a : b;
    }
  3. Kasus penggunaan lain, saya bisa memikirkan metode ini dikombinasikan dengan synchronizedmetode adalah implementasi penguncian tingkat kelas di lingkungan multi-threaded.

Katakanlah jika saya memiliki kelas dengan beberapa getter dan setter, satu atau dua metode, dan saya ingin metode-metode itu hanya tidak dapat disangkal pada objek instance kelas. Apakah ini berarti saya harus menggunakan metode statis?

Jika Anda perlu mengakses metode pada objek instan kelas, metode Anda seharusnya tidak statis.

Halaman dokumentasi Oracle memberikan rincian lebih lanjut.

Tidak semua kombinasi instance dan variabel kelas dan metode diizinkan:

  1. Metode instance dapat mengakses variabel instan dan metode instance secara langsung.
  2. Metode instance dapat mengakses variabel kelas dan metode kelas secara langsung.
  3. Metode kelas dapat mengakses variabel kelas dan metode kelas secara langsung.
  4. Metode kelas tidak dapat mengakses variabel instan atau metode instan secara langsung — mereka harus menggunakan referensi objek. Juga, metode kelas tidak dapat menggunakan kata kunci ini karena tidak ada contoh untuk merujuk.
Ravindra babu
sumber
Tidak bisakah kita mengakses bidang statis melalui metode biasa? Maka ini A common use for static methods is to access static fields.bukan argumen.
parsecer
2

Metode statis memiliki dua tujuan utama:

  1. Untuk metode utilitas atau bantuan yang tidak memerlukan status objek apa pun. Karena tidak perlu mengakses variabel instan, metode statis menghilangkan kebutuhan pemanggil untuk membuat instance objek hanya untuk memanggil metode.
  2. Untuk keadaan yang dibagikan oleh semua instance kelas, seperti penghitung. Semua instance harus memiliki status yang sama. Metode yang hanya menggunakan keadaan itu harus statis juga.
hemanto
sumber
1

Dalam gerhana Anda dapat mengaktifkan peringatan yang membantu Anda mendeteksi metode statis potensial. (Di atas garis yang disorot adalah satu lagi yang saya lupa tandai)

pengaturan gerhana

ave4496
sumber
0

Setiap kali Anda tidak ingin membuat objek untuk memanggil metode dalam kode Anda hanya menyatakan metode itu sebagai statis. Karena metode statis tidak memerlukan turunan untuk dipanggil dengan tetapi tangkapan di sini tidak semua metode statis dipanggil oleh JVM secara otomatis. Hak istimewa ini hanya dapat dinikmati dengan metode main () "public static void main [String ... args]" di java karena pada Runtime ini adalah metode Signature public "static" void main [] yang dicari oleh JVM sebagai titik masuk ke mulai eksekusi kode.

Contoh:

public class Demo
{
   public static void main(String... args) 
   {
      Demo d = new Demo();

      System.out.println("This static method is executed by JVM");

     //Now to call the static method Displ() you can use the below methods:
           Displ(); //By method name itself    
      Demo.Displ(); //By using class name//Recommended
         d.Displ(); //By using instance //Not recommended
   }

   public static void Displ()
   {
      System.out.println("This static method needs to be called explicitly");
   }
} 

Output: - Metode statis ini dijalankan oleh JVM. Metode statis ini perlu disebut secara eksplisit. Metode statis ini perlu disebut secara eksplisit. Metode statis ini perlu disebut secara eksplisit.

Amrit
sumber