Java Immutable (Değişmez) Sınıflar

Immutable (değişmez) sınıflar, nesneleri bir kez oluşturulduktan sonra nesne içeriği değiştirilemeyen sınıflardır. Bir nevi sabit sınıflardır diyebiliriz. Örneğin, Java’da String sınıfı değişmez sınıflardan bir tanesidir. Diğer bilinen değişmez sınıflardan bazıları, Integer, Double, Boolean, BigDecimal sınıflarıdır.

Gelin şimdi hem değişmez sınıfların özelliklerini görmek adına hem de değişmez bir sınıf nasıl yaratılır onu görmek adına bir sınıf yazalım.

public final class ImmutableMutant {
    
    private final String name;
    private final int numberOfArms;
    private final int numberOfLegs;
    
    public ImmutableMutant(final String name, final int numberOfArms,
                            final int numberOfLegs) {
        this.name = name;
        this.numberOfArms = numberOfArms;
        this.numberOfLegs = numberOfLegs;        
    }
    
    public String getName() {
        return name;
    }
    
    public int getNumberOfArms() {
        return numberOfArms;
    }
    
    public int getNumberOfLegs() {
        return numberOfLegs;
    }
}

Kodu incelediğimizde sınıfın final bir sınıf olduğunu görüyoruz. Sınıfı final olarak tanımlamanın amacı, sınıfın başka sınıflar tarafından extend edilmesini (türetilmesini) engellemek. Yani, final sınıfların alt sınıfları olmaz. Dolayısıyla değişmez sınıflardan herhangi bir şekilde başka sınıflar türetilemez.

İkinci olarak, sınıfın tüm elemanları private ve final‘dır. Yani, sınıf içinden veya dışından herhangi bir şekilde değiştirilemez.

Üçüncü olarak, sınıfın tüm elemanları sadece constructor vasıtasıyla ilklendirilebilir.

Ve son olarak, sınıf elemanlarını dışardan değiştirebilecek metodlar (setter metodları) yoktur.

Şimdi de değişmez sınıfların özellikleri ve avantajlarından bahsedelim. Değişmez sınıf nesneleri kesinlikle thread korumalıdır (thread-safe). Çünkü, bir kez oluşturulduktan sonra içeriği değiştirilemez bu da threadlerde kullanımda ortaya çıkabilecek senkronizasyon sorunlarını ortadan kaldırır. Değişmez sınıf nesnelerinin içerikleri değişmeyeceği için program akışı içerisinde içerikte istenmeyen değişikliklerin olmasının önüne geçilebilecektir. Değişmez sınıf nesnelerini gönül rahatlığıyla başka referanslara atayabilirsiniz. Örneğin, bir metoda yolladığınızda o metod içerisinde nesnenin değişmeyeceğini garanti etmiş olursunuz.

Java İpucu #2 – Java Konsola Yazı Yazdırma

Biraz da Java’ya yeni başlayan arkadaşlarımız için kısa bilgilendirme amaçlı yazılar yazmak istedim. Bir programlama dilini öğrenirken ilk öğrendiğimiz konudan başlayalım: Konsola yazı yazdırma.

Bir yazıyı ekrana nasıl basacağımızı gösteren küçük bir kod parçası yazalım;

System.out.println("Konsola basılacak ilk yazı");
String printTxt = "Konsola basılacak ikinci yazı";
System.out.println(printTxt);
System.out.print("Bundan sonra yazılacak yazı yanına gelecek - ");
System.out.print("Bir önceki yazının yanına gelecek yazı");

1. satırda println metodu doğrudan stringi argüman alarak konsola basıyor ve alt satıra geçiriyor. İngilizce açılımını print line (satır yaz) olarak düşünebiliriz. 3. satırda println metoduna 2. satırda oluşturduğumuz string nesnesini argüman olarak veriyoruz. 1. satırla benzer sonuç doğuruyor. 4 ve 5. satırlardaki print metodunun println metodundan farkı, gelen argümanı konsola bastıktan sonra alt satıra geçmeden bir sonraki ekrana yazma işleminin aynı satırdan devam etmesi.

Kod parçasının konsol çıktısı şu şekilde;

Konsola basılacak ilk yazı
Konsola basılacak ikinci yazı
Bundan sonra yazılacak yazı yanına gelecek - Bir önceki yazının yanına gelecek yazı

print ve println metodları String parametresinin yanında, diğer tüm primitive (int, char vb.) tipleri parametre olarak alabiliyor. Ayrıca bu metodlara Java kütüphanelerinde bulunan ya da kendi oluşturduğunuz tüm sınıfları da argüman olarak verebiliyorsunuz. Nasıl mı? Java’da tüm sınıfların ata sınıfı Object sınıfıdır. Ve bu sınıf çok sihirli bir metoda sahiptir: toString. Yani, tüm sınıflarınızın bir String karşılığı var. Bu metodu isterseniz kendi sınıfınızda override ederek içeriğini siz yazabilirsiniz. Bu işlemi yapmazsanız Object sınıfı sizin için bir gösterim yapıyor. Çok da anlamlı olmayabilir sizin için tabi 🙂

Hemen örnek kod;

Object o = new Object();
System.out.println(o);

ve konsol çıktısı;

java.lang.Object@42e816

Çıktının içeriği çok da önemli değil (meraklıları için söyleyeyim; sınıfın paket ismiyle beraber ismi ve hash kodu). Ama her sınıfın bir String karşılığı var bunu bilin yeter 🙂

Uyarı!

Bu noktadan sonrası tamamen meraklı ve usta kullanıcılar içindir. Uyarmadı demeyin 🙂

Örnek kod parçalarındaki

System.out.println

satırını irdeleyelim biraz. Bu satırda aslında, System sınınıfın out alanının println metodunu çağırıyoruz. System sınıfı nesnesi oluşturulamayan ve türetilemiyen bir sınıf  (final class). out, System sınıfının static bir alanı (değişkeni) ve PrintStream tipinde. print ve println metotları ise aslında PrintStream sınıfının metodları. Kendileri de static tabii ki 🙂

Uyarı Sonu

Basit bir konuyu çok da karmaşıklaştırmamak için daha detaya girmek istemiyorum. Diğer yazılarda yeri geldikçe yeniden değinmeye çalışırım. Herkese iyi çalışmalar.