Initializer Block ve Nesne Başlatma
Giriş
Constructor'ı biliyorsun — nesne oluşturulurken field'lara değer atamak için kullanılıyordu. static blok da gördük — sınıf yüklendiğinde çalışıyordu. Peki ya her nesne oluşturulurken, ama constructor'dan önce çalışan bir kod bloğu olsaydı?
İşte instance initializer block tam bu. Constructor, static block ve initializer block birlikte Java'nın başlatma mekanizmasını oluşturur. Bu derste hepsinin nasıl çalıştığını ve çalışma sırasını net olarak öğreneceksin.
Instance Initializer Block
Süslü parantezler içinde, metot dışında, static keyword'ü olmadan yazılan kod bloğu:
class Ornek {
int sayi;
// Instance initializer block
{
sayi = 42;
System.out.println("Instance initializer çalıştı");
}
Ornek() {
System.out.println("Constructor çalıştı");
}
}Ornek o = new Ornek();
// Çıktı:
// Instance initializer çalıştı
// Constructor çalıştıInstance initializer block, her nesne oluşturulduğunda, constructor'dan önce çalışır.
Instance Initializer'ın bir ortak başlatma kodu gibi düşün
Bunu bir otel odası hazırlığı gibi düşün. Her misafir gelmeden önce oda temizlenir, çarşaflar değiştirilir (initializer block). Sonra misafirin özel istekleri karşılanır — ekstra yastık, mini bar (constructor). Her misafir için temel hazırlık aynı, özel istekler farklı.
Neden Instance Initializer Kullanılır?
1. Birden Fazla Constructor'da Ortak Kod
class Kullanici {
String isim;
String rol;
ArrayList<String> loglar;
// Bu kod her constructor'da tekrarlanırdı
{
loglar = new ArrayList<>();
loglar.add("Nesne oluşturuldu: " + java.time.LocalDateTime.now());
}
Kullanici(String isim) {
this.isim = isim;
this.rol = "USER";
}
Kullanici(String isim, String rol) {
this.isim = isim;
this.rol = rol;
}
}Her iki constructor'dan önce de loglar başlatılıyor. Constructor chaining (this()) ile de yapılabilirdi, ama bazen initializer block daha temiz.
2. Anonymous Class'larda Constructor Yazılamaz
Anonymous class'ların ismi olmadığı için constructor yazılamaz. Initializer block burada tek seçenek:
Runnable gorev = new Runnable() {
// Constructor yazamayız — isim yok!
// Initializer block ile başlatma
{
System.out.println("Görev hazırlanıyor...");
}
@Override
public void run() {
System.out.println("Görev çalışıyor.");
}
};Bu, instance initializer block'un en meşru kullanım alanıdır.
Static Initializer Block (Tekrar)
Önceki derste kısaca gördük, şimdi karşılaştırma amacıyla tekrar bakalım:
class Veritabani {
static String url;
static int port;
// Static initializer — sınıf yüklendiğinde BİR KEZ çalışır
static {
url = "localhost";
port = 3306;
System.out.println("Static initializer çalıştı");
}
}System.out.println(Veritabani.url);
System.out.println(Veritabani.url);
// Çıktı:
// Static initializer çalıştı
// localhost
// localhostStatic blok sadece bir kez çalışır, sınıf belleğe ilk yüklendiğinde.
Static vs Instance Initializer
| Özellik | Static Initializer | Instance Initializer |
|---|---|---|
| Keyword | static { } | { } |
| Ne zaman çalışır | Sınıf yüklendiğinde | Her nesne oluşturulduğunda |
| Kaç kez çalışır | 1 kez | Nesne sayısı kadar |
| Neye erişir | Sadece static üyelere | Hem static hem instance |
Çalışma Sırası — Kritik Konu
Bu kısım sınavlarda ve mülakatlarda çok sorulur. Sırayı doğru bilmek gerekir.
Temel Sıra
class Sira {
static int staticField = degerVer("1. Static field");
int instanceField = degerVer("3. Instance field");
static {
System.out.println("2. Static initializer block");
}
{
System.out.println("4. Instance initializer block");
}
Sira() {
System.out.println("5. Constructor");
}
static int degerVer(String mesaj) {
System.out.println(mesaj);
return 0;
}
}System.out.println("--- İlk nesne ---");
Sira s1 = new Sira();
System.out.println("--- İkinci nesne ---");
Sira s2 = new Sira();Çıktı:
--- İlk nesne ---
1. Static field
2. Static initializer block
3. Instance field
4. Instance initializer block
5. Constructor
--- İkinci nesne ---
3. Instance field
4. Instance initializer block
5. ConstructorSıra Kuralı
Static üyeler (field + static blok) — sınıf yüklendiğinde, bir kez, yazıldıkları sırayla
Instance üyeler (field + instance blok) — her nesne oluşturulduğunda, yazıldıkları sırayla
Constructor — en son
Formül:
Static field/block (1 kez) → Instance field/block (her new'de) → Constructor (her new'de)⚠️ Dikkat: Static başlatma sadece ilk nesne oluşturulduğunda (veya sınıfa ilk erişildiğinde) yapılır. İkinci nesnede static kısım tekrar çalışmaz.
Birden Fazla Blok
Birden fazla static ve instance blok olabilir. Yazıldıkları sırayla çalışırlar:
class CokBlok {
{
System.out.println("Instance blok 1");
}
{
System.out.println("Instance blok 2");
}
static {
System.out.println("Static blok 1");
}
static {
System.out.println("Static blok 2");
}
CokBlok() {
System.out.println("Constructor");
}
}new CokBlok();Çıktı:
Static blok 1
Static blok 2
Instance blok 1
Instance blok 2
ConstructorPratik Örnek: ID Üreteci
class Siparis {
private static int sayac;
private static final String PREFIX;
// Static başlatma
static {
sayac = 1000;
PREFIX = "SIP";
System.out.println("Sipariş sistemi başlatıldı.");
}
private String siparisNo;
private String urun;
private java.time.LocalDateTime olusturmaZamani;
// Instance başlatma — her sipariş için
{
sayac++;
siparisNo = PREFIX + "-" + sayac;
olusturmaZamani = java.time.LocalDateTime.now();
}
Siparis(String urun) {
this.urun = urun;
}
void bilgiGoster() {
System.out.println(siparisNo + " | " + urun + " | " + olusturmaZamani);
}
}Siparis s1 = new Siparis("Laptop");
Siparis s2 = new Siparis("Telefon");
Siparis s3 = new Siparis("Kulaklık");
s1.bilgiGoster(); // SIP-1001 | Laptop | ...
s2.bilgiGoster(); // SIP-1002 | Telefon | ...
s3.bilgiGoster(); // SIP-1003 | Kulaklık | ...Static blok sistemi bir kez başlatıyor. Instance blok her siparişe otomatik numara ve zaman atıyor. Constructor sadece ürüne özel bilgiyi alıyor.
Ne Zaman Kullanılır?
Instance Initializer Kullan:
Anonymous class'larda (constructor yazılamadığı için)
Tüm constructor'larda ortak olan karmaşık başlatma kodu varsa
Instance Initializer Kullanma:
Basit atamalar için → direkt field tanımında yap:
int x = 5;Constructor'da yapılabilecek şeyler için → constructor daha okunabilir
Static Initializer Kullan:
Static field'ların karmaşık başlatması (dosya okuma, konfigürasyon)
Exception fırlatabilecek static başlatmalar
Static Initializer Kullanma:
Basit sabit atamalar için →
static final int X = 5;yeterli
💡 İpucu: Pratikte instance initializer block çok sık kullanılmaz. Constructor çoğu durumda yeterli ve daha okunabilir. Ama çalışma sırasını bilmek, mülakat ve sınavlar için çok önemli. Static initializer ise gerçek projelerde konfigürasyon yüklemek için sıkça kullanılır.
Field Başlatma Yolları — Karşılaştırma
class Ornek {
// Yol 1: Doğrudan atama
int a = 10;
// Yol 2: Instance initializer
int b;
{
b = 20;
}
// Yol 3: Constructor
int c;
Ornek() {
c = 30;
}
// Yol 4: Static (static field için)
static int d = 40;
// Yol 5: Static initializer (static field için)
static int e;
static {
e = 50;
}
}Hangisini ne zaman?
Basit değer → doğrudan atama (
int a = 10;)Karmaşık hesaplama gerekiyorsa → constructor veya initializer
Static field → doğrudan atama veya static blok
Her constructor'da lazım + anonymous class → instance initializer
Yaygın Sınav Sorusu
class Test {
static { System.out.print("A "); }
{ System.out.print("B "); }
Test() { System.out.print("C "); }
{ System.out.print("D "); }
static { System.out.print("E "); }
}
public class Main {
public static void main(String[] args) {
new Test();
System.out.println();
new Test();
}
}Çıktı:
A E B D C
B D CAçıklama:
İlk
new Test(): Static bloklar (A, E) → Instance bloklar (B, D) → Constructor (C)İkinci
new Test(): Static bloklar çalışmaz (zaten çalıştı) → Instance bloklar (B, D) → Constructor (C)
Özet
Instance initializer block (
{ }) her nesne oluşturulduğunda, constructor'dan önce çalışırStatic initializer block (
static { }) sınıf yüklendiğinde bir kez çalışırÇalışma sırası: static field/block → instance field/block → constructor
Instance initializer en çok anonymous class'larda kullanılır (constructor yazılamadığı için)
Static initializer konfigürasyon yükleme gibi karmaşık static başlatmalar için kullanılır
Birden fazla blok varsa yazıldıkları sırayla çalışırlar
AI Asistan
Sorularını yanıtlamaya hazır