Adalah kesalahpahaman umum untuk berpikir bahwa blok statis hanya memiliki akses ke bidang statis. Untuk ini saya ingin menunjukkan potongan kode di bawah ini yang sering saya gunakan dalam proyek kehidupan nyata (disalin sebagian dari jawaban lain dalam konteks yang sedikit berbeda):
public enum Language {
ENGLISH("eng", "en", "en_GB", "en_US"),
GERMAN("de", "ge"),
CROATIAN("hr", "cro"),
RUSSIAN("ru"),
BELGIAN("be",";-)");
static final private Map<String,Language> ALIAS_MAP = new HashMap<String,Language>();
static {
for (Language l:Language.values()) {
// ignoring the case by normalizing to uppercase
ALIAS_MAP.put(l.name().toUpperCase(),l);
for (String alias:l.aliases) ALIAS_MAP.put(alias.toUpperCase(),l);
}
}
static public boolean has(String value) {
// ignoring the case by normalizing to uppercase
return ALIAS_MAP.containsKey(value.toUpper());
}
static public Language fromString(String value) {
if (value == null) throw new NullPointerException("alias null");
Language l = ALIAS_MAP.get(value);
if (l == null) throw new IllegalArgumentException("Not an alias: "+value);
return l;
}
private List<String> aliases;
private Language(String... aliases) {
this.aliases = Arrays.asList(aliases);
}
}
Di sini penginisialisasi digunakan untuk mempertahankan indeks ( ALIAS_MAP
), untuk memetakan set alias kembali ke tipe enum asli. Ini dimaksudkan sebagai perluasan ke metode valueOf bawaan yang disediakan oleh Enum
dirinya sendiri.
Seperti yang Anda lihat, penginisialisasi statis mengakses bahkan private
bidang aliases
. Penting untuk memahami bahwa static
blok sudah memiliki akses ke Enum
instance nilai (misalnya ENGLISH
). Ini karena urutan inisialisasi dan eksekusi dalam kasus Enum
tipe , seperti jika static private
bidang telah diinisialisasi dengan instance sebelum static
blok dipanggil:
- The
Enum
konstanta yang bidang statis implisit. Ini memerlukan konstruktor Enum dan blok instance, dan inisialisasi instance juga terjadi terlebih dahulu.
static
blok dan inisialisasi bidang statis dalam urutan kejadian.
Inisialisasi rusak ini (konstruktor sebelum static
blok) penting untuk dicatat. Ini juga terjadi ketika kita menginisialisasi bidang statis dengan instance yang mirip dengan Singleton (penyederhanaan dibuat):
public class Foo {
static { System.out.println("Static Block 1"); }
public static final Foo FOO = new Foo();
static { System.out.println("Static Block 2"); }
public Foo() { System.out.println("Constructor"); }
static public void main(String p[]) {
System.out.println("In Main");
new Foo();
}
}
Apa yang kita lihat adalah output berikut:
Static Block 1
Constructor
Static Block 2
In Main
Constructor
Yang jelas adalah bahwa inisialisasi statis sebenarnya dapat terjadi sebelum konstruktor, dan bahkan setelah:
Cukup mengakses Foo dalam metode utama, menyebabkan kelas dimuat dan inisialisasi statis dimulai. Tetapi sebagai bagian dari inisialisasi Statis kita kembali memanggil konstruktor untuk bidang statis, setelah itu melanjutkan inisialisasi statis, dan melengkapi konstruktor yang dipanggil dari dalam metode utama. Situasi yang agak rumit yang saya harap dalam coding normal kita tidak harus berurusan dengan.
Untuk info lebih lanjut tentang ini, lihat buku " Java Efektif ".
{...}
vsstatic {...}
. (dalam hal ini Jon Skeet pasti menjawab pertanyaan Anda dengan lebih baik)