ProgramlamaOrta/Kıdemli Java Geliştirici

Java'da class initialization order nedir, nasıl çalışır ve statik ve dinamik üyelerin başlatma sırasını yanlış anlama hangi sonuçlara yol açabilir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

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:

  1. Statik alanlar ve statik başlatıcılar, sınıf yüklendiğinde JVM tarafından, sınıf içindeki görünüm sırasına göre (sınıf başına bir kez) çalıştırılır.
  2. Dinamik alanlar ve başlatıcılar, her bir örnek oluşturulduğunda, yapıcı çağrılmadan önce, görünüm sırasına göre çalıştırılır.
  3. Yapıcı, tüm alanların ve blokların başlatılmasından sonra çalıştırılır.

Örnek

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:

  1. Parent static
  2. Child static
  3. Parent init
  4. Parent constructor
  5. Child init
  6. Child constructor

Ö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.

Kandırmaca Sorusu.

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.

Gerçek hata örnekleri bu konudaki ince detayların bilinmemesinden kaynaklı.


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.