Saya tidak mendapatkan pemahaman lengkap tentang konstruktor statis di Jawa. Jika diizinkan, mengapa diizinkan? Dalam skenario apa Anda akan menggunakannya? Apa tujuannya? Bisakah seseorang memberi saya contoh sederhana?
Berbagi penelitian Anda membantu semua orang. Beri tahu kami apa yang telah Anda coba dan mengapa itu tidak memenuhi kebutuhan Anda. Ini menunjukkan bahwa Anda telah meluangkan waktu untuk mencoba membantu diri sendiri, itu menyelamatkan kami dari mengulangi jawaban yang jelas, dan yang paling utama itu membantu Anda mendapatkan jawaban yang lebih spesifik dan relevan. Lihat juga Cara Meminta
nyamuk
3
Tidak ada yang namanya "konstruktor statis".
David Conrad
Jawaban:
28
Sebenarnya, Java tidak memiliki konstruktor statis karena konstruktor, menurut definisi, tidak boleh statis. Apa yang Anda maksud disebut "blok inisialisasi statis." Konstruktor menyiratkan bahwa Anda membangun objek. Anda tidak dapat memiliki konstruktor untuk kelas karena kelas bukan turunan dari kelas itu sendiri. Ini hanyalah sebuah kelas. Hal yang "membangun" kelas disebut kompiler (atau mesin virtual, tergantung pada apa yang dimaksud dengan "konstruksi"), dan jika Anda masuk ke membangun kode dalam kode lain, Anda masuk ke pembuatan kode, yang merupakan binatang yang sama sekali berbeda.
Semua samping, nit, blok inisialisasi statis digunakan untuk menginisialisasi bidang statis (atau tingkat kelas) kompleks untuk kelas. Biasanya ini digunakan untuk menginisialisasi hal-hal yang tidak dapat diinisialisasi dalam satu baris, atau mengharuskan beberapa objek lain (yang mungkin atau mungkin tidak ada di kelas di mana blok statis diimplementasikan) diinisialisasi terlebih dahulu.
Pada dasarnya, seseorang dapat menggunakannya untuk memberi tahu kelas "Hei, atur variabel A ke nilai ini PERTAMA, lalu, setelah selesai, gunakan nilai A untuk menginisialisasi B." Karena Java mengharuskan inisialisasi bidang standar dilakukan baik di dalam konstruktor atau metode, atau melalui panggilan konstruktor atau metode (kecuali itu adalah literal), ini dapat menjadi metode yang nyaman untuk menginisialisasi objek yang kompleks dan statis.
Blok inisialisasi statis tidak terlalu sering dibutuhkan, dan umumnya harus dihindari kecuali mereka benar - benar digunakan. Jangan salah, mereka memiliki tempat di Jawa, tetapi seperti banyak hal lain (seperti pernyataan break, return, switch, dan goto) mereka dapat dengan mudah digunakan, yang mengurangi keterbacaan dan pemeliharaan kode. -Basis mereka digunakan dalam.
Contoh singkat dari blok inisialisasi statis yang digunakan adalah sebagai berikut (sesuai dengan penjelasan yang sangat baik dari blok inisialisasi statis yang ditemukan di sini ):
Kode:
publicclassStaticExample{static{System.out.println("This is first static block");}publicStaticExample(){System.out.println("This is constructor");}publicstaticString staticString ="Static Variable";static{System.out.println("This is second static block and "+ staticString);}publicstaticvoid main(String[] args){StaticExample statEx =newStaticExample();StaticExample.staticMethod2();}static{
staticMethod();System.out.println("This is third static block");}publicstaticvoid staticMethod(){System.out.println("This is static method");}publicstaticvoid staticMethod2(){System.out.println("This is static method2");}}
Keluaran:
This is first static block
This is second static block and Static Variable
This is static method
This is third static block
This is constructor
This is static method2
Beberapa contoh mereka daftar ketika blok statis dapat berguna:
Jika Anda memuat driver dan item lain ke namespace. Sebagai contoh, kelas Kelas memiliki blok statis di mana ia mendaftarkan penduduk asli.
Jika Anda perlu melakukan perhitungan untuk menginisialisasi variabel statis Anda, Anda dapat mendeklarasikan blok statis yang dijalankan tepat sekali, ketika kelas dimuat pertama kali.
Masalah terkait keamanan atau tugas terkait pencatatan
Beberapa alasan untuk TIDAK menggunakan blok statis (dalam situasi lain):
Ada batasan JVM bahwa blok penginisialisasi statis tidak boleh melebihi 64K.
Anda tidak dapat membuang Pengecualian yang Dicentang.
Anda tidak dapat menggunakan thiskata kunci karena tidak ada contoh.
Anda tidak boleh mencoba mengakses super karena tidak ada hal seperti itu untuk blok statis.
Anda seharusnya tidak mengembalikan apa pun dari blok ini.
Blok statis membuat pengujian mimpi buruk.
Saya harus perhatikan: Walaupun beberapa bahasa (seperti C #) mungkin memiliki sintaks untuk "konstruktor" yang statis, "konstruktor" itu berfungsi seperti halnya blok inisialisasi statis di Jawa, dan dilihat oleh banyak orang (termasuk saya) sebagai misnomers dalam bahasa, diberikan konsep dasar konstruktor OOP .
tidak mungkin untuk mengisi peta pada inisialisasi (kecuali jika Anda menggunakan hack subclass anonim) jadi ini adalah cara terbaik untuk menjamin itu diisi sebelum digunakan pertama kali
Anda juga dapat melakukan ini untuk menangkap pengecualian yang diperiksa saat inisialisasi
Ini sangat banyak salah satu kegunaan utama yang telah saya lihat tetapi dengan dimasukkannya metode pabrik statis untuk kerangka koleksi di Jawa 9 kasus penggunaan ini benar-benar telah ditinggalkan dengan cara.
Hangman4358
2
Jawaban Gurgadurgen mungkin adalah yang Anda cari, tetapi saya hanya akan menambahkan beberapa poin lain yang kadang-kadang diabaikan ketika seseorang menginginkan "konstruktor statis".
Jika Anda menginginkan metode statis yang membuat instance kelas Anda, Anda bisa membuat metode statis yang hanya memanggil konstruktor kelas.
publicclassExample{/** Static method to create an instance. */publicstaticExample build(){returnnewExample();}/** A field of each instance. */privateString stuff ;/** The class's actual constructor. */publicExample(){ stuff =newString();}publicString getStuff(){returnthis.stuff ;}/**
* Mutator for "stuff" property. By convention this returns "void"
* but you might want to return the object itself, to support the
* sort of chained invocations that are becoming trendy now. You'll
* see the stylistic benefits of chaining later in this example.
*/publicExample setStuff(String newStuff ){this.stuff = newStuff ;returnthis;}}publicclassExampleTest{publicstaticvoid main(String[] args ){// The usual instance model.Example first =newExample();System.out.println( first.setStuff("stuff").getStuff());// Using your static method to construct an instance:Example second =Example.build();System.out.println( second.setStuff("more stuff").getStuff());// Chaining all the invocations at once:System.out.println(Example.build().setStuff("even more stuff").getStuff());}}
Ini menghasilkan output:
stuff
more stuff
even more stuff
Alasan lain untuk membuat metode statis untuk membangun sebuah instance adalah kasus ketika Anda ingin memastikan bahwa tepat satu instance dari kelas Anda ada pada waktu tertentu; ini disebut singleton . Dengan konvensi, kelas semacam itu akan menyediakan metode statis yang dipanggil getInstance()untuk mendapatkan satu-satunya instance yang diperlakukan sebagai "singleton".
publicclassSingletonExampleextendsExample{// Note: This extends my previous example, which has a "stuff"// property, and a trivial constructor./** The singleton instance, statically initialized as null. */privatestaticSingletonExample singleton =null;/**
* The static accessor for the singleton. If no instance exists,
* then it will be created; otherwise, the one that already exists
* will be returned.
*/publicstaticSingletonExample getInstance(){if( singleton ==null)
singleton =newSingletonExample();return singleton ;}}publicclassSingletonExampleTest{publicstaticvoid main(String[] args ){System.out.println(SingletonExample.getInstance().setStuff("stuff").getStuff());// You could still create instances of this class normally if you want to.SingletonExample otherstuff =newSingletonExample();
otherstuff.setStuff("other stuff");// But watch what happens to this.System.out.println(SingletonExample.getInstance().getStuff());System.out.println( otherstuff.getStuff());// Now we show what happens when you start modifying the singleton.SingletonExample theoneandonly =SingletonExample.getInstance();
theoneandonly.setStuff("changed stuff");System.out.println(SingletonExample.getInstance().getStuff());}}
Ini menghasilkan yang berikut ini.
stuff
stuff
other stuff
changed stuff
Dengan menyimpan referensi ke singleton, dan kemudian memodifikasinya, panggilan selanjutnya untuk getInstance()mendapatkan singleton yang dimodifikasi itu.
Sangat menggoda untuk menggunakan lajang sebagai cara untuk mulai membuat variabel global untuk aplikasi Anda. Dalam beberapa konteks ini bisa berguna, tetapi juga bisa membuat Anda kesulitan. Secara khusus saya mengalami bug yang menarik saat mengembangkan aplikasi Android, di mana contoh tunggal bisa hilang. Melompat dari satu aktivitas ke aktivitas lain terkadang dapat mengarahkan JVM untuk menggunakan "kelas pemuat" baru yang tidak akan tahu tentang singleton yang disimpan secara statis oleh pemuat kelas sebelumnya.
Sementara saya mengerti bahwa ada banyak orang yang melihat gagasan "konstruktor statis" sebagai istilah yang keliru, saya tidak percaya itu yang terjadi. Masalahnya adalah dalam proses membangun kelas dan objek instance mereka . Telah dinyatakan di utas lain bahwa konstruksi kelas adalah pekerjaan kompilator. Bahkan di Jawa, ini hanya setengah benar.
Compiler membuat scaffold untuk setiap definisi kelas. Scaffold berisi metadata tentang kelas dan contoh apa yang harus ada di dalamnya pada saat konstruksi. Jika kelas mendefinisikan bidang yang diberi nilai primitif konstan, maka nilai itu termasuk dalam scaffold oleh kompiler. Untuk jenis nilai lain yang ditugaskan, kompiler menghasilkan rutin inisialisasi yang harus dijalankan 1 kali, sebelum pembuatan instance kelas pertama, yang memperbarui perancah dengan nilai yang tepat. Pembaruan ini tidak dapat dilakukan oleh kompiler.
Karena pembaruan satu kali ini untuk perancah sering merupakan prasyarat penting untuk berfungsinya konstruktor instance, juga masuk akal untuk menyebutnya jenis konstruktor. Inilah sebabnya mengapa dalam bahasa OO umum yang mendukung konsep, itu disebut konstruktor statis. Konsep di balik blok inisialisasi statis di Jawa adalah sedikit lebih dari perubahan semantik untuk tetap sejalan dengan gagasan bahwa seorang programmer Java harus menjadi sistem dan implementasi agnostik.
Seperti jawaban lain katakan, Anda dapat menulis metode statis yang membangun objek. Ini mengatasi kurangnya konstruktor bernama di Jawa (dan banyak bahasa lainnya. Delphi mendukung konstruktor bernama). Anda dapat bermain dengan tipe dan urutan parameter tetapi ini dapat menyebabkan kode tidak jelas dan rapuh.
Misalnya, kami dapat membuat skenario di mana objek Anda dapat dibangun dari string XML atau string JSON. Anda dapat menulis metode seperti:
Ketika saya membaca pertanyaan, ini tentang inisialisasi statis, bukan tentang emthod statis normal.
CodesInChaos
-2
Anda dapat melihat bagian "statis" seperti yang digunakan konstruktor tingkat kelas untuk menginisialisasi properti kelas (statis di java). Sama seperti konstruktor "normal" yang digunakan untuk menginisialisasi properti tingkat instance.
Jawaban:
Sebenarnya, Java tidak memiliki konstruktor statis karena konstruktor, menurut definisi, tidak boleh statis. Apa yang Anda maksud disebut "blok inisialisasi statis." Konstruktor menyiratkan bahwa Anda membangun objek. Anda tidak dapat memiliki konstruktor untuk kelas karena kelas bukan turunan dari kelas itu sendiri. Ini hanyalah sebuah kelas. Hal yang "membangun" kelas disebut kompiler (atau mesin virtual, tergantung pada apa yang dimaksud dengan "konstruksi"), dan jika Anda masuk ke membangun kode dalam kode lain, Anda masuk ke pembuatan kode, yang merupakan binatang yang sama sekali berbeda.
Semua samping, nit, blok inisialisasi statis digunakan untuk menginisialisasi bidang statis (atau tingkat kelas) kompleks untuk kelas. Biasanya ini digunakan untuk menginisialisasi hal-hal yang tidak dapat diinisialisasi dalam satu baris, atau mengharuskan beberapa objek lain (yang mungkin atau mungkin tidak ada di kelas di mana blok statis diimplementasikan) diinisialisasi terlebih dahulu.
Pada dasarnya, seseorang dapat menggunakannya untuk memberi tahu kelas "Hei, atur variabel A ke nilai ini PERTAMA, lalu, setelah selesai, gunakan nilai A untuk menginisialisasi B." Karena Java mengharuskan inisialisasi bidang standar dilakukan baik di dalam konstruktor atau metode, atau melalui panggilan konstruktor atau metode (kecuali itu adalah literal), ini dapat menjadi metode yang nyaman untuk menginisialisasi objek yang kompleks dan statis.
Blok inisialisasi statis tidak terlalu sering dibutuhkan, dan umumnya harus dihindari kecuali mereka benar - benar digunakan. Jangan salah, mereka memiliki tempat di Jawa, tetapi seperti banyak hal lain (seperti pernyataan break, return, switch, dan goto) mereka dapat dengan mudah digunakan, yang mengurangi keterbacaan dan pemeliharaan kode. -Basis mereka digunakan dalam.
Contoh singkat dari blok inisialisasi statis yang digunakan adalah sebagai berikut (sesuai dengan penjelasan yang sangat baik dari blok inisialisasi statis yang ditemukan di sini ):
Kode:
Keluaran:
Beberapa contoh mereka daftar ketika blok statis dapat berguna:
Beberapa alasan untuk TIDAK menggunakan blok statis (dalam situasi lain):
this
kata kunci karena tidak ada contoh.Saya harus perhatikan: Walaupun beberapa bahasa (seperti C #) mungkin memiliki sintaks untuk "konstruktor" yang statis, "konstruktor" itu berfungsi seperti halnya blok inisialisasi statis di Jawa, dan dilihat oleh banyak orang (termasuk saya) sebagai misnomers dalam bahasa, diberikan konsep dasar konstruktor OOP .
sumber
digunakan untuk menginisialisasi bidang yang lebih sulit daripada hanya menugaskannya:
tidak mungkin untuk mengisi peta pada inisialisasi (kecuali jika Anda menggunakan hack subclass anonim) jadi ini adalah cara terbaik untuk menjamin itu diisi sebelum digunakan pertama kali
Anda juga dapat melakukan ini untuk menangkap pengecualian yang diperiksa saat inisialisasi
sumber
Jawaban Gurgadurgen mungkin adalah yang Anda cari, tetapi saya hanya akan menambahkan beberapa poin lain yang kadang-kadang diabaikan ketika seseorang menginginkan "konstruktor statis".
Jika Anda menginginkan metode statis yang membuat instance kelas Anda, Anda bisa membuat metode statis yang hanya memanggil konstruktor kelas.
Ini menghasilkan output:
Alasan lain untuk membuat metode statis untuk membangun sebuah instance adalah kasus ketika Anda ingin memastikan bahwa tepat satu instance dari kelas Anda ada pada waktu tertentu; ini disebut singleton . Dengan konvensi, kelas semacam itu akan menyediakan metode statis yang dipanggil
getInstance()
untuk mendapatkan satu-satunya instance yang diperlakukan sebagai "singleton".Ini menghasilkan yang berikut ini.
Dengan menyimpan referensi ke singleton, dan kemudian memodifikasinya, panggilan selanjutnya untuk
getInstance()
mendapatkan singleton yang dimodifikasi itu.Sangat menggoda untuk menggunakan lajang sebagai cara untuk mulai membuat variabel global untuk aplikasi Anda. Dalam beberapa konteks ini bisa berguna, tetapi juga bisa membuat Anda kesulitan. Secara khusus saya mengalami bug yang menarik saat mengembangkan aplikasi Android, di mana contoh tunggal bisa hilang. Melompat dari satu aktivitas ke aktivitas lain terkadang dapat mengarahkan JVM untuk menggunakan "kelas pemuat" baru yang tidak akan tahu tentang singleton yang disimpan secara statis oleh pemuat kelas sebelumnya.
sumber
Sementara saya mengerti bahwa ada banyak orang yang melihat gagasan "konstruktor statis" sebagai istilah yang keliru, saya tidak percaya itu yang terjadi. Masalahnya adalah dalam proses membangun kelas dan objek instance mereka . Telah dinyatakan di utas lain bahwa konstruksi kelas adalah pekerjaan kompilator. Bahkan di Jawa, ini hanya setengah benar.
Compiler membuat scaffold untuk setiap definisi kelas. Scaffold berisi metadata tentang kelas dan contoh apa yang harus ada di dalamnya pada saat konstruksi. Jika kelas mendefinisikan bidang yang diberi nilai primitif konstan, maka nilai itu termasuk dalam scaffold oleh kompiler. Untuk jenis nilai lain yang ditugaskan, kompiler menghasilkan rutin inisialisasi yang harus dijalankan 1 kali, sebelum pembuatan instance kelas pertama, yang memperbarui perancah dengan nilai yang tepat. Pembaruan ini tidak dapat dilakukan oleh kompiler.
Karena pembaruan satu kali ini untuk perancah sering merupakan prasyarat penting untuk berfungsinya konstruktor instance, juga masuk akal untuk menyebutnya jenis konstruktor. Inilah sebabnya mengapa dalam bahasa OO umum yang mendukung konsep, itu disebut konstruktor statis. Konsep di balik blok inisialisasi statis di Jawa adalah sedikit lebih dari perubahan semantik untuk tetap sejalan dengan gagasan bahwa seorang programmer Java harus menjadi sistem dan implementasi agnostik.
sumber
Seperti jawaban lain katakan, Anda dapat menulis metode statis yang membangun objek. Ini mengatasi kurangnya konstruktor bernama di Jawa (dan banyak bahasa lainnya. Delphi mendukung konstruktor bernama). Anda dapat bermain dengan tipe dan urutan parameter tetapi ini dapat menyebabkan kode tidak jelas dan rapuh.
Misalnya, kami dapat membuat skenario di mana objek Anda dapat dibangun dari string XML atau string JSON. Anda dapat menulis metode seperti:
Saya sering menggunakan ini sebagai alternatif untuk konstruktor tanpa parameter dengan metode inisialisasi bernama:
Anda bisa melihat metode pembuatan statis sebagai menerapkan pola pembangun di dalam kelas Anda.
sumber
Anda dapat melihat bagian "statis" seperti yang digunakan konstruktor tingkat kelas untuk menginisialisasi properti kelas (statis di java). Sama seperti konstruktor "normal" yang digunakan untuk menginisialisasi properti tingkat instance.
sumber