Statik bir bloğun yalnızca statik alanlara erişimi olduğunu düşünmek yaygın bir yanlış anlamadır. Bunun için gerçek hayat projelerinde oldukça sık kullandığım kod parçasının altında göstermek istiyorum ( biraz farklı bir bağlamda kısmen başka bir cevaptan kopyalandı ):
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);
}
}
Burada başlatıcı, ALIAS_MAP
bir dizi diğer adı orijinal numara türüne geri eşlemek için bir dizini ( ) korumak için kullanılır . Enum
Kendisi tarafından sağlanan yerleşik valueOf yönteminin bir uzantısı olarak tasarlanmıştır .
Gördüğünüz gibi, statik başlatıcı private
alana bile erişir aliases
. static
Bloğun zaten Enum
değer örneklerine (ör. ENGLISH
) Erişimi olduğunu anlamak önemlidir . Bunun nedeni, türler durumunda başlatmalar ve yürütme sırasınınEnum
, tıpkı bloklar çağrılmadan static private
önce alanlar örneklerle başlatılmış gibi olmasıdır static
:
Enum
Örtük statik alanlardır sabitler. Bu, Enum yapıcısının ve örnek bloklarının ve örnek başlatmanın önce gerçekleşmesini gerektirir.
static
statik alanların oluşma sırasına göre bloklanması ve başlatılması.
Bu sıra dışı başlatma ( static
bloktan önce yapıcı ) not etmek önemlidir. Statik alanları bir Singleton örneğine benzer şekilde başlattığımızda da olur (basitleştirmeler yapıldı):
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();
}
}
Gördüğümüz şu çıktı:
Static Block 1
Constructor
Static Block 2
In Main
Constructor
Açıktır ki, statik başlatma aslında kurucudan önce ve sonra olabilir:
Ana yöntemde sadece Foo'ya erişmek, sınıfın yüklenmesine ve statik başlatmanın başlamasına neden olur. Ancak Statik başlatmanın bir parçası olarak, tekrar statik alanlar için yapıcıları çağırırız, daha sonra statik başlatmayı sürdürür ve ana yöntemden çağrılan yapıcıyı tamamlar. Oldukça karmaşık bir durum için umarım normal kodlamada uğraşmak zorunda kalmayacağız.
Bu konuda daha fazla bilgi için " Etkili Java " kitabına bakınız .
{...}
vs arasındaki farkı bildiğinizi düşündümstatic {...}
. (bu durumda Jon Skeet sorunuza daha iyi cevap verdi)