Takip et

Java Record Compact Constructor’lar: Yapıcıları Geri Kazanmak

Java Record Compact Constructor’lar: Yapıcıları Geri Kazanmak Java 16 ile hayatımıza giren Record’lar, veri taşıyıcı sınıflar yazma biçimimizi k…

Java Record Compact Constructor’lar: Yapıcıları Geri Kazanmak

Java 16 ile hayatımıza giren Record’lar, veri taşıyıcı sınıflar yazma biçimimizi kökten değiştirdi. Geleneksel olarak, veri tutan sınıflar için boilerplate kod yazmak zorunda kalırdık: yapıcılar, equals(), hashCode(), toString() metodları, getter’lar… Record’lar tüm bu yükü üzerimizden alarak kodumuzu sadeleştirdi. Ancak Record’lar, veri doğrulama gibi kritik operasyonlar için özel bir yapıya, yani “Compact Constructor”lara ihtiyaç duyar. Bu makalede, Java Record’ların compact constructor’larını detaylıca inceleyecek, ne işe yaradıklarını, nasıl kullanıldıklarını ve neden bu kadar değerli olduklarını keşfedeceğiz.

Java Record’ların Temelleri ve Neden İhtiyaç Duyuldu?

Java’da veri taşıyıcı sınıflar oluşturmak, uzun yıllar boyunca geliştiriciler için tekrarlayan ve hataya açık bir süreç olmuştur. Bu sınıflar genellikle sadece veri depolamak ve bu verilere erişim sağlamakla yükümlüydü, ancak bu basit görev için bile önemli miktarda kod yazmak gerekiyordu. Java Record’lar, bu soruna zarif ve etkili bir çözüm sunarak modern Java geliştirmesinde önemli bir yer edinmiştir.

Veri Taşıyıcı Sınıfların Zorlukları

Birçok uygulamada, sadece veri tutmak ve bu verileri immutable (değişmez) bir şekilde temsil etmek için sınıflara ihtiyaç duyarız. Örneğin, bir kullanıcının adı ve e-posta adresi gibi bilgileri içeren bir User sınıfı. Geleneksel yaklaşımda, bu sınıfı oluştururken şunları yazmak zorunda kalırdık: tüm alanlar için private final tanımlamalar, bir yapıcı metot, her alan için getter metodları, equals(), hashCode() ve toString() metodları. Bu, nispeten basit bir veri yapısı için bile yüzlerce satır kod anlamına gelebilirdi ve bu kodun büyük bir kısmı tekrarlayıcıydı. Bu durum, hem geliştirme süresini uzatıyor hem de bakım maliyetini artırıyordu.

Record’ların Tanımı ve Amacı

Java 16 ile tanıtılan Record’lar, bu “veri taşıyıcı” sınıfları tanımlamanın daha kısa ve öz bir yolunu sunar. Bir Record, değişmez veriler için tasarlanmış şeffaf bir taşıyıcıdır. record anahtar kelimesiyle tanımlanır ve derleyici, Record’un bileşenleri (alanları) için otomatik olarak şunları üretir:

  • Tüm bileşenleri içeren bir “canonical constructor” (standart yapıcı).
  • Her bileşen için bir erişimci metot (getter yerine doğrudan alan adıyla erişim).
  • equals() ve hashCode() metodları.
  • toString() metodu.

Bu otomasyon sayesinde geliştiriciler, veri modelleme konusunda daha az boilerplate kod yazarak iş mantığına odaklanabilirler.

Basit Bir Record Örneği

Bir Record’un ne kadar basit olduğunu göstermek için klasik Point örneğini ele alalım:


public record Point(int x, int y) {
    // Record body (isteğe bağlı)
}

Bu tek satırlık tanım, x ve y koordinatlarına sahip, değişmez bir Point nesnesi oluşturmak için gereken tüm temel işlevselliği sağlar. new Point(10, 20) şeklinde bir nesne oluşturabilir, point.x() ve point.y() ile değerlerine erişebiliriz. Geleneksel sınıflara kıyasla ne kadar az kod yazdığımıza dikkat edin.

Geleneksel Yapıcılar ve Sınırlamaları

Java'da yapıcılar, bir sınıfın nesnelerini başlatmak için kullanılan özel metotlardır. Record'lar da dahil olmak üzere her sınıfın en az bir yapıcısı bulunur. Ancak Record'ların yapıcıları, geleneksel sınıfların yapıcılarına göre bazı farklılıklar ve özel kullanım senaryoları sunar.

Standart Yapıcı Davranışı

Geleneksel bir Java sınıfında, eğer açıkça bir yapıcı tanımlamazsanız, Java derleyicisi sizin için bağımsız değişken almayan (no-arg) varsayılan bir yapıcı oluşturur. Bu yapıcı, üst sınıfın no-arg yapıcısını çağırır. Eğer parametreli bir yapıcı tanımlarsanız, varsayılan no-arg yapıcı otomatik olarak oluşturulmaz. Yapıcıların temel amacı, nesnenin durumunu ilk oluşturulduğunda geçerli ve tutarlı bir hale getirmektir.

Parametreli Yapıcılar ve this() Kullanımı

Çoğu zaman, bir nesnenin ilk durumunu ayarlamak için parametreler alan yapıcılar tanımlarız. Bu yapıcılar içinde genellikle gelen parametreleri sınıfın alanlarına atarız. Bir yapıcının başka bir yapıcıyı çağırması gerektiğinde ise this() anahtar kelimesini kullanırız. Bu, yapıcı zincirleme olarak bilinir ve kod tekrarını azaltmak için faydalıdır. Ancak, this() çağrısı her zaman yapıcının ilk ifadesi olmak zorundadır.


public class TraditionalUser {
    private final String name;
    private final String email;

    public TraditionalUser(String name, String email) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("Name cannot be null or empty");
        }
        this.name = name;
        this.email = email;
    }

    public TraditionalUser(String name) {
        this(name, "default@example.com"); // this() ile zincirleme
    }

    // getters, equals, hashCode, toString...
}

Record'larda Geleneksel Yapıcıların Durumu

Record'lar, derleyici tarafından otomatik olarak üretilen bir "canonical constructor"a sahiptir. Bu yapıcı, Record'un tüm bileşenlerini (alanlarını) parametre olarak alır ve bu parametreleri doğrudan ilgili alanlara atar. Geleneksel sınıfların aksine, Record'larda varsayılan bir no-arg yapıcı bulunmaz çünkü Record'lar her zaman tüm bileşenleriyle başlatılmalıdır.

Record'larda geleneksel yapıcılar tanımlamak mümkündür, ancak bunlar her zaman ya Record'un canonical constructor'ını (veya compact constructor'ını) çağırmak zorundadır ya da diğer bir Record yapıcıyı zincirleme olarak çağırmalıdır. Bu, Record'un değişmezlik ilkesini ve bileşenlerinin doğru şekilde başlatılmasını sağlamak için kritik bir kısıtlamadır. Bu kısıtlama, Record'ların veri bütünlüğünü koruma konusunda ne kadar kararlı olduğunu gösterir.

Compact Constructor Nedir?

Java Record'lar ile birlikte gelen en güçlü özelliklerden biri de "Compact Constructor"lardır. Adından da anlaşılacağı gibi, bu yapıcılar standart yapıcıların daha kısa, daha yoğun bir formudur ve özellikle veri doğrulama gibi görevler için tasarlanmıştır.

Sözdizimi ve Temel Yapı

Compact constructor, Record'un tüm bileşenlerini parametre olarak almasına rağmen, bu parametreleri açıkça bildirmek zorunda kalmadığımız özel bir yapıcı türüdür. Sözdizimi, Record'un adını alır, ancak parantez içinde parametre listesi bulunmaz. İçerisinde, parametrelerin alanlara atanması (yani this.x = x; gibi ifadeler) otomatik olarak derleyici tarafından yapılır. Geliştirici sadece doğrulama veya normalleştirme mantığını yazar.


public record Product(String name, double price) {
    // Compact Constructor
    public Product {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Product name cannot be null or blank.");
        }
        if (price <= 0) {
            throw new IllegalArgumentException("Product price must be positive.");
        }
        // name ve price alanlarına atama derleyici tarafından otomatik yapılır.
    }
}

Yukarıdaki örnekte, Product Record'u için bir compact constructor tanımladık. Bu constructor içinde name ve price parametrelerinin geçerliliğini kontrol ediyoruz. Eğer bir hata varsa IllegalArgumentException fırlatıyoruz. Dikkat ederseniz, this.name = name; veya this.price = price; gibi atama ifadeleri yazmadık. Bu, compact constructor'ın temel özelliğidir.

Canonical Constructor ile Farkı

Her Record, derleyici tarafından otomatik olarak üretilen bir "canonical constructor"a sahiptir. Bu yapıcı, Record'un tüm bileşenlerini parametre olarak alır ve bu parametreleri doğrudan ilgili alanlara atar. Örneğin, Product(String name, double price) Record'u için derleyici şu canonical constructor'ı üretir:


// Derleyici tarafından üretilen canonical constructor (mantıksal olarak)
public Product(String name, double price) {
    this.name = name;
    this.price = price;
}

Compact constructor ise, bu canonical constructor'ın bir ön işleme adımı gibidir. Compact constructor içinde yazdığınız kod, derleyici tarafından üretilen canonical constructor'ın alan atamalarından *önce* çalıştırılır. Yani, compact constructor'ın bitiminde, derleyici otomatik olarak parametreleri ilgili alanlara atar. Bu, compact constructor'ı özellikle veri doğrulama, normalleştirme veya türetilmiş alanları hesaplama için ideal kılar.

Implicit Alan Ataması

Compact constructor'ın en önemli özelliği, parametrelerin Record bileşenlerine (alanlarına) otomatik olarak atanmasıdır. Geliştiricinin this.field = field; gibi ifadeler yazmasına gerek kalmaz. Bu, kod tekrarını büyük ölçüde azaltır ve Record'ların ana felsefesine, yani "az kodla çok iş yapma"ya uygun bir yaklaşımdır. Atama işlemi, compact constructor'ın kod bloğu tamamlandıktan hemen sonra gerçekleşir. Bu sayede, constructor içinde doğrulama veya manipülasyon yapabilir, ancak alan atama sorumluluğunu derleyiciye bırakabilirsiniz. Bu durum, Record'ların değişmezlik garantisini ve veri bütünlüğünü koruma yeteneğini güçlendirir.

Compact Constructor Kullanım Senaryoları ve Avantajları

Compact constructor'lar, Record'ların gücünü artıran ve geliştiricilere daha temiz, güvenli kod yazma imkanı sunan çok yönlü bir özelliktir. Özellikle veri bütünlüğünü sağlamak ve kod tekrarını azaltmak için idealdir.

Veri Bütünlüğünü Sağlama

Bir Record nesnesi oluşturulduğunda, içerdiği verilerin belirli kurallara uyması gerekebilir. Örneğin, bir yaşın negatif olmaması, bir e-posta adresinin geçerli bir formatta olması veya bir fiyatın sıfırdan büyük olması gibi. Compact constructor'lar, bu tür ön koşul kontrollerini doğrudan nesne oluşturma aşamasında yapmamızı sağlar. Bu sayede, uygulama içinde geçersiz bir Record nesnesinin oluşmasını engelleyerek veri bütünlüğünü garanti altına alırız. Eğer doğrulama başarısız olursa, bir IllegalArgumentException fırlatarak durumu açıkça belirtiriz. Bu yaklaşım, nesnenin her zaman geçerli bir durumda olmasını sağlar ve daha sonraki kodda geçersiz verilerle uğraşma ihtiyacını ortadan kaldırır.


public record Person(String name, int age) {
    public Person {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Name cannot be null or blank.");
        }
        if (age <= 0) {
            throw new IllegalArgumentException("Age must be positive.");
        }
        // name = name.trim(); // Normalleştirme de yapılabilir
    }
}

Gereksiz Kod Tekrarını Azaltma

Geleneksel sınıflarda, veri doğrulama mantığını birden fazla yapıcıda veya hatta farklı metotlarda tekrarlamak zorunda kalabilirdik. Compact constructor, bu doğrulama mantığını tek bir merkezi yerde, yani Record'un yapıcı aşamasında toplar. Record'un canonical constructor'ı (derleyici tarafından üretilen) her zaman bu compact constructor'ı çağıracağı için, doğrulama mantığının her zaman çalışacağından emin olabiliriz. Bu, kod tekrarını önemli ölçüde azaltır ve bakımını kolaylaştırır. Ayrıca, this.field = field; gibi alan atama ifadelerinin derleyici tarafından otomatik olarak halledilmesi de kod kalabalığını azaltır.

Kod Okunabilirliğini Artırma

Compact constructor'lar, Record'un temel amacını (veri taşıma) bozmadan, veri doğrulama ve normalleştirme gibi yan görevleri şık bir şekilde entegre etmemizi sağlar. Parametre listesinin olmaması ve otomatik alan ataması sayesinde, yapıcı bloğu sadece doğrulama mantığına odaklanır. Bu, kodu daha okunabilir ve anlaşılır hale getirir. Bir Record'un tanımına baktığınızda, hangi verilerin kabul edilebilir olduğunu ve hangi kısıtlamalara sahip olduğunu hemen anlayabilirsiniz. Bu şeffaflık, özellikle büyük projelerde veya ekip çalışmalarında kodun anlaşılmasını ve sürdürülebilirliğini artırır.

Compact Constructor ile Veri Doğrulama

Compact constructor'lar, Record nesnelerinin oluşturulması sırasında veri doğrulama yapmak için ideal bir mekanizma sunar. Bu sayede, immutable Record'ların her zaman geçerli bir durumda olmasını sağlayabiliriz.

Ön Koşul Kontrolleri

Bir Record'un bileşenlerinin belirli koşulları sağlaması gerektiğinde ön koşul kontrolleri yaparız. Örneğin, bir metin alanının boş olmaması veya bir sayının belirli bir aralıkta olması gibi. Compact constructor, bu kontrolleri nesne oluşturulmadan hemen önce gerçekleştirmek için mükemmel bir yerdir. Eğer bir koşul sağlanmazsa, genellikle IllegalArgumentException fırlatarak geçersiz durumu bildiririz. Bu, Record'un değişmez yapısı gereği, nesne bir kere oluşturulduktan sonra durumunun değiştirilemeyeceği için özellikle önemlidir.


public record Task(String description, int priority) {
    public Task {
        if (description == null || description.trim().isEmpty()) {
            throw new IllegalArgumentException("Description cannot be null or empty.");
        }
        if (priority < 1 || priority > 10) {
            throw new IllegalArgumentException("Priority must be between 1 and 10.");
        }
        // description = description.trim(); // Normalleştirme de burada yapılabilir
    }
}

Null Kontrolleri

Java'da NullPointerException (NPE) yaygın bir sorundur. Compact constructor'lar, Record bileşenlerinin null olup olmadığını kontrol etmek için etkili bir yöntem sunar. Eğer bir bileşenin null olmaması gerekiyorsa, constructor içinde basit bir null kontrolü yaparak bu durumu engelleyebiliriz. Bu, özellikle Record'ların veri bütünlüğünü koruma felsefesiyle uyumludur, çünkü null değerler genellikle beklenmedik davranışlara yol açabilir.


import java.util.Objects;

public record Email(String recipient, String subject, String body) {
    public Email {
        Objects.requireNonNull(recipient, "Recipient cannot be null.");
        Objects.requireNonNull(subject, "Subject cannot be null.");
        Objects.requireNonNull(body, "Body cannot be null.");
    }
}

Objects.requireNonNull() metodu, null kontrolü yapmak ve null olması durumunda belirtilen mesajla bir NullPointerException fırlatmak için kullanışlı bir yardımcıdır.

Değer Aralık Kontrolleri

Sayısal değerler veya tarihler gibi bileşenler genellikle belirli bir aralıkta olmalıdır. Örneğin, bir ürünün fiyatı negatif olamaz veya bir tarih gelecekte olmalıdır. Compact constructor'lar, bu tür aralık kontrollerini kolayca uygulamamızı sağlar. Bu sayede, Record nesnelerinin her zaman mantıksal olarak geçerli değerlere sahip olmasını garantileyebiliriz.


public record Temperature(double value, String unit) {
    public Temperature {
        if (unit == null || unit.isBlank()) {
            throw new IllegalArgumentException("Unit cannot be null or blank.");
        }
        if (!unit.equalsIgnoreCase("C") && !unit.equalsIgnoreCase("F")) {
            throw new IllegalArgumentException("Unit must be 'C' or 'F'.");
        }
        // Fahrenhayt'ı Celsius'a dönüştürme gibi normalizasyonlar da yapılabilir
        // if (unit.equalsIgnoreCase("F")) {
        //     value = (value - 32) * 5 / 9;
        //     unit = "C";
        // }
    }
}

Bu örnekte, Temperature Record'unun unit bileşeninin belirli değerler arasında olmasını sağlıyoruz. Ayrıca, bu bölümde gösterildiği gibi, compact constructor'lar sadece doğrulama için değil, aynı zamanda gelen verileri normalleştirmek veya dönüştürmek için de kullanılabilir.

Compact Constructor ve Canonical Constructor İlişkisi

Compact constructor'lar, Record'ların temel yapıcı mekanizması olan canonical constructor ile yakından ilişkilidir. Bu ilişkiyi anlamak, Record'ların nasıl çalıştığını ve compact constructor'ların ne zaman ve neden kullanıldığını kavramak için kritik öneme sahiptir.

Canonical Constructor'ın Rolü

Her Record için Java derleyicisi otomatik olarak bir "canonical constructor" üretir. Bu yapıcı, Record'un tüm bileşenlerini (alanlarını) sırasıyla parametre olarak alır ve bu parametreleri doğrudan Record'un ilgili final alanlarına atar. Bu, Record'un değişmez (immutable) doğasının temelini oluşturur. Örneğin, record Point(int x, int y) {} tanımı için derleyici, mantıksal olarak şöyle bir canonical constructor oluşturur:


// Derleyici tarafından üretilen canonical constructor (mantıksal olarak)
public Point(int x, int y) {
    this.x = x;
    this.y = y;
}

Bu constructor, Record nesnesinin ilk ve tek geçerli başlatma noktasını temsil eder. Diğer tüm yapıcılar (eğer tanımlanmışsa), doğrudan veya dolaylı olarak bu canonical constructor'ı çağırmak zorundadır.

Compact Constructor'ın Genişletilmiş Rolü

Compact constructor, aslında bu otomatik olarak üretilen canonical constructor'ın bir "ön işleme" bloğu gibidir. Compact constructor içinde yazdığınız kod, derleyici tarafından üretilen alan atamalarından *önce* çalıştırılır. Yani, bir Record nesnesi oluşturulduğunda, süreç şu adımları izler:
1. Compact constructor'ın kodu çalıştırılır (veri doğrulama, normalleştirme vb.).
2. Compact constructor'ın kodu tamamlandıktan sonra, derleyici otomatik olarak Record'un bileşenlerini parametrelerden ilgili final alanlarına atar.

Bu, compact constructor'ı veri doğrulama, normalleştirme veya türetilmiş değerleri hesaplama için mükemmel bir yer haline getirir. Compact constructor'ın parametre listesi olmaması ve otomatik alan ataması, kodun daha kısa ve okunabilir olmasını sağlar.

Derleyici Davranışı

Derleyici, bir Record'da compact constructor tanımlandığını gördüğünde, canonical constructor'ı şu şekilde yeniden yazar (mantıksal olarak):


public record Product(String name, double price) {
    public Product { // Compact Constructor
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("Product name cannot be null or blank.");
        }
        if (price <= 0) {
            throw new IllegalArgumentException("Product price must be positive.");
        }
    }
}

// Derleyici tarafından üretilen canonical constructor'ın iç mantığı (mantıksal olarak):
// public Product(String name, double price) {
//     // Compact constructor'ın kodu buraya eklenir
//     if (name == null || name.isBlank()) {
//         throw new IllegalArgumentException("Product name cannot be null or blank.");
//     }
//     if (price <= 0) {
//         throw new IllegalArgumentException("Product price must be positive.");
//     }
//     // Otomatik alan atamaları
//     this.name = name;
//     this.price = price;
// }

Görüldüğü gibi, compact constructor'ın kodu, nihai alan atamalarından önce çalıştırılır. Bu yapı, Record'ların değişmezlik garantisini bozmadan, nesne oluşturma anında veri bütünlüğünü sağlamak için güçlü ve temiz bir yol sunar. Geliştirici olarak, sadece doğrulama veya manipülasyon mantığını yazarız; alan atama yükünü derleyiciye bırakırız.

İyi Uygulamalar ve Dikkat Edilmesi Gerekenler

Compact constructor'lar güçlü bir araç olsa da, onları doğru ve etkili bir şekilde kullanmak için bazı iyi uygulamaları takip etmek ve potansiyel tuzaklara dikkat etmek önemlidir.

Yalnızca Gerekliyse Kullanım

Compact constructor'lar, Record'lar için veri doğrulama ve normalleştirme gibi özel durumlar için tasarlanmıştır. Eğer bir Record'un bileşenleri üzerinde herhangi bir doğrulama veya manipülasyon yapmanıza gerek yoksa, compact constructor tanımlamak gereksizdir. Bu durumda, derleyicinin otomatik olarak ürettiği canonical constructor yeterli olacaktır. Gereksiz yere compact constructor kullanmak, kodu karmaşıklaştırabilir ve Record'ların temel sadeliğini bozabilir. Her zaman "en basit çözüm en iyisidir" prensibini hatırlayın.

Basit ve Odaklı Doğrulama

Compact constructor'lar içinde karmaşık iş mantığı veya yan etkileri olan işlemlerden kaçınmak önemlidir. Constructor'ın temel amacı, nesnenin durumunu geçerli ve tutarlı hale getirmektir. Bu nedenle, doğrulama mantığı mümkün olduğunca basit, anlaşılır ve odaklı olmalıdır. Ağ çağrıları, veritabanı işlemleri veya diğer dış sistemlerle etkileşim gibi ağır operasyonlar constructor içinde yapılmamalıdır. Bu tür işlemler, nesne oluşturma sürecini yavaşlatabilir ve test edilebilirliği zorlaştırabilir. Constructor'ı, Record'un kendi içindeki verilerin geçerliliğini sağlamakla sınırlı tutun.

Hata Yönetimi

Compact constructor içinde doğrulama başarısız olduğunda, uygun bir istisna fırlatmak önemlidir. Genellikle IllegalArgumentException veya NullPointerException gibi çalışma zamanı istisnaları kullanılır. Bu istisnalar, nesnenin geçersiz bir durumda oluşturulmaya çalışıldığını açıkça belirtir. İstisna mesajları açıklayıcı olmalı ve sorunun ne olduğunu net bir şekilde ifade etmelidir. Bu, hata ayıklama sürecini kolaylaştırır ve API'nizi kullanan diğer geliştiricilere yol gösterir.


public record Age(int value) {
    public Age {
        if (value < 0 || value > 120) {
            throw new IllegalArgumentException("Age must be between 0 and 120, but was: " + value);
        }
    }
}

Bu örnekte, istisna mesajına geçersiz değeri de ekleyerek hatanın daha kolay anlaşılmasını sağlıyoruz. İyi bir hata yönetimi, uygulamanızın sağlamlığını ve kullanıcı deneyimini artırır.

Sonuç

Java Record'lar, veri taşıyıcı sınıflar yazma biçimimizde devrim yaratarak boilerplate kodu ortadan kaldırmış ve geliştiricilerin daha temiz, okunabilir ve sürdürülebilir kodlar yazmasını sağlamıştır. Bu devrimin önemli bir parçası da compact constructor'lardır. Compact constructor'lar, Record'ların değişmezlik ilkesini korurken, nesne oluşturma aşamasında güçlü veri doğrulama ve normalleştirme yetenekleri sunar.

Compact constructor'lar sayesinde, veri bütünlüğünü garantileyebilir, gereksiz kod tekrarını azaltabilir ve kod okunabilirliğini artırabiliriz. Canonical constructor ile olan ilişkisi, derleyicinin otomatik alan atamalarını ne zaman ve nasıl gerçekleştirdiğini anlamamızı sağlar. Doğru kullanıldığında, compact constructor'lar Java uygulamalarınızın sağlamlığını ve güvenilirliğini önemli ölçüde artırabilir. Java geliştiricileri olarak, bu modern özelliği benimseyerek daha verimli ve hatasız veri modelleri oluşturabiliriz.

SSS (Sık Sorulan Sorular)

1. Compact constructor nedir ve ne zaman kullanılmalıdır?

Compact constructor, Java Record'lar için özel bir yapıcı türüdür. Record'un tüm bileşenlerini parametre olarak alır ancak bunları açıkça bildirme ihtiyacı duymazsınız. Temel olarak, Record'un alanlarına değerler atanmadan *önce* çalıştırılacak doğrulama, normalleştirme veya dönüştürme mantığını yazmak için kullanılır. Özellikle veri bütünlüğünü sağlamak, null kontrolleri yapmak veya değer aralıklarını kontrol etmek gerektiğinde kullanılmalıdır.

2. Compact constructor ile canonical constructor arasındaki fark nedir?

Canonical constructor, Record'un tüm bileşenlerini parametre olarak alan ve bu parametreleri doğrudan ilgili final alanlara atayan, derleyici tarafından otomatik olarak üretilen standart yapıcıdır. Compact constructor ise, bu canonical constructor'ın bir "ön işleme" bloğu gibidir. Compact constructor içindeki kod, canonical constructor'ın otomatik alan atamalarından *önce* çalışır. Compact constructor parametre listesi içermez ve alan atamaları derleyici tarafından otomatik yapılır.

3. Compact constructor içinde this.field = field; gibi atamalar yapabilir miyim?

Evet, yapabilirsiniz, ancak bu genellikle önerilmez ve compact constructor'ın ana amacına aykırıdır. Compact constructor'ın temel özelliği, alan atamalarının derleyici tarafından otomatik olarak yapılmasıdır. Eğer this.field = someValue; gibi bir atama yaparsanız, bu değer derleyicinin otomatik atamasını geçersiz kılar. Genellikle compact constructor'lar sadece doğrulama ve normalleştirme için kullanılır; atama sorumluluğu derleyiciye bırakılır.

4. Bir Record'da birden fazla compact constructor tanımlayabilir miyim?

Hayır, bir Record'da yalnızca bir tane compact constructor tanımlayabilirsiniz. Compact constructor, Record'un tek canonical constructor'ının bir uzantısıdır ve bu nedenle tekil olmak zorundadır. Ancak, Record'larda başka yardımcı yapıcılar (custom constructors) tanımlayabilirsiniz, ancak bu yardımcı yapıcıların her zaman compact constructor'ı veya canonical constructor'ı çağırması gerekir.

5. Compact constructor içinde hangi tür istisnaları fırlatmalıyım?

Genellikle IllegalArgumentException veya NullPointerException gibi çalışma zamanı istisnaları fırlatılmalıdır. IllegalArgumentException, bir argümanın geçerli olmadığı durumlar için uygundur (örneğin, negatif yaş, boş dize). NullPointerException ise beklenen bir değerin null olması durumunda kullanılır. İstisna mesajlarının açıklayıcı ve sorunu net bir şekilde belirten bilgiler içermesi önemlidir.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.