Saya bertanya-tanya kapan variabel statis diinisialisasi ke nilai defaultnya. Apakah benar bahwa ketika kelas dimuat, vars statis dibuat (dialokasikan), kemudian penginisialisasi dan inisialisasi statis dalam deklarasi dijalankan? Pada titik manakah nilai default diberikan? Ini mengarah pada masalah referensi ke depan.
Juga tolong jika Anda dapat menjelaskan ini dengan mengacu pada pertanyaan yang diajukan di Mengapa bidang statis tidak diinisialisasi tepat waktu? dan terutama jawaban yang diberikan oleh Kevin Brock di situs yang sama. Saya tidak dapat memahami poin ke-3.
java
static
initialization
Ankit
sumber
sumber
Jawaban:
Dari Lihat Metode Variabel Statis Jawa :
Variabel instans dan kelas (statis) secara otomatis diinisialisasi ke nilai default standar jika Anda gagal menginisialisasi mereka dengan sengaja. Meskipun variabel lokal tidak diinisialisasi secara otomatis, Anda tidak dapat mengkompilasi program yang gagal menginisialisasi variabel lokal atau menetapkan nilai ke variabel lokal tersebut sebelum digunakan.
Apa yang sebenarnya dilakukan oleh compiler adalah secara internal menghasilkan rutinitas inisialisasi kelas tunggal yang menggabungkan semua penginisialisasi variabel statis dan semua blok penginisialisasi statis dari kode, dalam urutan yang muncul di deklarasi kelas. Prosedur inisialisasi tunggal ini dijalankan secara otomatis, hanya satu kali, saat kelas pertama kali dimuat.
Dalam kasus kelas dalam , mereka tidak boleh memiliki bidang statis
Lihat JLS 8.1.3 Kelas Dalam dan Mesin Virtual Penutup
final
bidang di Jawa dapat diinisialisasi secara terpisah dari tempat deklarasinya, namun ini tidak dapat diterapkan kestatic final
bidang. Lihat contoh di bawah ini.final class Demo { private final int x; private static final int z; //must be initialized here. static { z = 10; //It can be initialized here. } public Demo(int x) { this.x=x; //This is possible. //z=15; compiler-error - can not assign a value to a final variable z } }
Hal ini karena hanya ada satu salinan dari
static
variabel yang terkait dengan jenis, bukan dari satu terkait dengan setiap contoh dari jenis seperti dengan variabel contoh dan jika kita mencoba untuk menginisialisasiz
jenisstatic final
dalam constructor, itu akan mencoba untuk reinitializestatic final
bidang jenisz
karena konstruktor dijalankan pada setiap instance kelas yang tidak boleh terjadi padafinal
bidang statis .sumber
In case of static inner classes, they can not have static fields
Sepertinya salah ketik. Kelas dalam tidak statis.Lihat:
Yang terakhir secara khusus menyediakan langkah - langkah inisialisasi mendetail yang menjelaskan kapan variabel statis diinisialisasi, dan dalam urutan apa (dengan peringatan bahwa
final
variabel kelas dan bidang antarmuka yang merupakan konstanta waktu kompilasi diinisialisasi terlebih dahulu.)Saya tidak yakin apa pertanyaan spesifik Anda tentang poin 3 (anggap saja maksud Anda yang bersarang?). Urutan rinci menyatakan ini akan menjadi permintaan inisialisasi rekursif sehingga akan melanjutkan inisialisasi.
sumber
Bidang statis diinisialisasi saat kelas dimuat oleh pemuat kelas. Nilai default ditetapkan saat ini. Ini dilakukan secara berurutan daripada yang muncul di kode sumber.
sumber
Urutan inisialisasi adalah:
Detail proses dijelaskan dalam dokumen spesifikasi JVM .
sumber
variabel statis
sumber
Dimulai dengan kode dari pertanyaan lain:
class MyClass { private static MyClass myClass = new MyClass(); private static final Object obj = new Object(); public MyClass() { System.out.println(obj); // will print null once } }
Referensi ke kelas ini akan memulai inisialisasi. Pertama, kelas akan ditandai sebagai diinisialisasi. Kemudian bidang statis pertama akan diinisialisasi dengan instance baru MyClass (). Perhatikan bahwa myClass segera diberi referensi ke instance MyClass kosong . Ada ruang di sana, tetapi semua nilai adalah nol. Konstruktor sekarang dijalankan dan dicetak
obj
, yang nilainya null.Sekarang kembali ke inisialisasi kelas:
obj
dibuat referensi ke objek nyata baru, dan kita selesai.Jika ini dipicu oleh pernyataan seperti:
MyClass mc = new MyClass();
ruang untuk instance MyClass baru dialokasikan lagi (dan referensi ditempatkan dimc
). Konstruktor dieksekusi lagi dan mencetak lagiobj
, yang sekarang bukan null.Trik sebenarnya di sini adalah ketika Anda menggunakan
new
, seperti diWhatEverItIs weii = new WhatEverItIs( p1, p2 );
weii
segera diberikan referensi ke sedikit memori nulled. JVM kemudian akan melanjutkan untuk menginisialisasi nilai dan menjalankan konstruktor. Tetapi jika Anda entah bagaimana mereferensikanweii
sebelum melakukannya - dengan mereferensikannya dari utas lain atau dengan merujuk dari inisialisasi kelas, misalnya - Anda melihat instance kelas yang diisi dengan nilai null.sumber
Variabel statis dapat diinisialisasi dalam tiga cara berikut sebagai berikut, pilih salah satu yang Anda suka
atau bisa anda lakukan dengan membuat blok statis misal:
static { // whatever code is needed for initialization goes here }
Ada alternatif untuk blok statis - Anda dapat menulis metode statis pribadi
class name { public static varType myVar = initializeVar(); private static varType initializeVar() { // initialization code goes here } }
sumber