Java'daki sınıf başlatma sırası (class initialization order), alanların, blokların ve yapıcıların hangi sırayla başlatılacağını belirler. Kısaca:
class Parent { static { System.out.println("Parent static"); } { System.out.println("Parent init"); } Parent() { System.out.println("Parent constructor"); } } class Child extends Parent { static { System.out.println("Child static"); } { System.out.println("Child init"); } Child() { System.out.println("Child constructor"); } } // new Child() -> hangi sıra?
Çıktı şöyle olacaktır:
Önce ebeveynlerin statik blokları, sonra çocukların statik blokları, ardından dinamik bloklar ve yapıcılar, miras alma sırasına göre çalıştırılır.
Soru: Aşağıdaki sınıfta statik başlatıcılar ne zaman çalıştırılacaktır:
class Ex {
static { System.out.println("static"); }
}
— İlk örnek oluşturulduğunda mı yoksa herhangi bir statik yöntem/alanına ilk erişimde mi?
Cevap: Statik başlatıcı, sınıfa ilk erişimde, herhangi bir statik üye (yöntem/alan) dahil olmak üzere, çalıştırılır, sadece örnek oluşturulduğunda değil.
Hikaye
Bir bankacılık uygulamasında, statik bağlantı havuzu statik blokta başlatıldı, ancak ilk örnekten önce bir statik yönteme başvurulduğundan bağlantı henüz oluşturulmadı. Bu, yük altında çalışırken NullPointerException'a yol açtı.
Hikaye
Günlük servisi, ana sınıfın yapıcı çağrısından sonra başlatılan bir dinamik alana bağlıydı. Günlükler null günlük okuyucuya yazıldı ve önemli hata mesajları kayboldu.
Hikaye
Yeni bir alan başlangıç değeri eklenirken, geliştirici bunu başlatma bloğundan sonra yerleştirdi: blok, henüz başlatılmamış bir alanı kullanmaya çalışıyor, bu da uygulamanın başlangıç hatalarına ve sorunun zor bulunmasına neden oluyordu.