0Pricing
Java Academy · Pelajaran

Konstruktor Ringkas dan Validasi

Tambahkan logika validasi di dalam konstruktor ringkas untuk memastikan integritas data.

Konstruktor Ringkas dan Validasi adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.

Konstruktor Ringkas

Konstruktor ringkas dalam record dijalankan sebelum komponen ditetapkan. Konstruktor ini memungkinkan Anda memvalidasi atau menormalisasi data tanpa mengulangi penetapan komponen.

Konstruktor Standar vs Konstruktor Ringkas

Konstruktor kanonis standar menetapkan komponen secara eksplisit. Konstruktor ringkas menghilangkan daftar parameter dan penetapan — keduanya dilakukan secara otomatis setelah badan konstruktor selesai dijalankan.

// Standard canonical constructor
record Range(int min, int max) {
    Range(int min, int max) {
        if (min > max) throw new IllegalArgumentException("min > max");
        this.min = min;  // explicit assignment
        this.max = max;
    }
}

// Compact constructor (same behavior, less code)
record Range2(int min, int max) {
    Range2 {  // no parameter list, no assignments
        if (min > max) throw new IllegalArgumentException("min > max");
        // components are assigned automatically after this block
    }
}

Validasi dalam Konstruktor Ringkas

Konstruktor ringkas adalah cara standar untuk memvalidasi data record. Lemparkan pengecualian sejak awal untuk menegakkan invarian.

record Email(String address) {
    Email {
        if (address == null || address.isBlank())
            throw new IllegalArgumentException("Email cannot be blank");
        if (!address.contains("@"))
            throw new IllegalArgumentException("Invalid email: " + address);
        address = address.toLowerCase().strip(); // normalize (Java 16+)
    }
}

Email e = new Email("  Alice@Example.com  ");
System.out.println(e.address()); // alice@example.com

try { new Email("not-an-email"); }
catch (IllegalArgumentException ex) { System.out.println(ex.getMessage()); }

Normalisasi dalam Konstruktor Ringkas

Anda dapat mengubah variabel komponen di dalam konstruktor ringkas sebelum variabel tersebut ditetapkan. Dengan demikian, data dinormalisasi saat konstruksi.

record PersonName(String firstName, String lastName) {
    PersonName {
        firstName = capitalize(firstName);
        lastName  = capitalize(lastName);
    }

    private static String capitalize(String s) {
        if (s == null || s.isEmpty()) return s;
        return Character.toUpperCase(s.charAt(0)) +
               s.substring(1).toLowerCase();
    }

    public String fullName() { return firstName + " " + lastName; }
}

PersonName name = new PersonName("jOHN", "DOE");
System.out.println(name.fullName()); // John Doe

Penyalinan Defensif

Untuk komponen yang dapat diubah seperti array atau koleksi, lakukan penyalinan defensif dalam konstruktor ringkas untuk mempertahankan sifat tidak dapat diubah.

import java.util.*;

record Snapshot(List<String> items) {
    Snapshot {
        items = List.copyOf(items); // defensive copy — unmodifiable
    }
}

List<String> mutable = new ArrayList<>(List.of("a", "b", "c"));
Snapshot snap = new Snapshot(mutable);
mutable.add("d"); // doesn't affect snapshot
System.out.println(snap.items()); // [a, b, c]

try {
    snap.items().add("e"); // UnsupportedOperationException
} catch (UnsupportedOperationException e) {
    System.out.println("Snapshot is truly immutable!");
}

Record Range dengan Batas

Record Range praktis yang memastikan min <= max dan menyediakan metode utilitas yang berguna.

record Range(int min, int max) {
    Range {
        if (min > max) throw new IllegalArgumentException(
            "min (" + min + ") must be <= max (" + max + ")");
    }

    public boolean contains(int value) { return value >= min && value <= max; }
    public int size()  { return max - min; }
    public int clamp(int value) { return Math.max(min, Math.min(max, value)); }
}

Range valid = new Range(1, 10);
System.out.println(valid.contains(5));  // true
System.out.println(valid.clamp(15));    // 10
System.out.println(valid.size());       // 9

Merangkai Logika Konstruktor Ringkas

Untuk validasi yang kompleks, pisahkan metode pembantu lalu panggil metode tersebut dari konstruktor ringkas.

record CreditCard(String number, String cvv, int expiryMonth, int expiryYear) {
    CreditCard {
        validateNumber(number);
        validateCvv(cvv);
        validateExpiry(expiryMonth, expiryYear);
        number = number.replaceAll("[^0-9]", ""); // strip spaces/dashes
    }

    private static void validateNumber(String n) {
        String digits = n.replaceAll("[^0-9]", "");
        if (digits.length() < 13 || digits.length() > 19)
            throw new IllegalArgumentException("Invalid card number length");
    }
    private static void validateCvv(String cvv) {
        if (!cvv.matches("[0-9]{3,4}"))
            throw new IllegalArgumentException("Invalid CVV");
    }
    private static void validateExpiry(int m, int y) {
        if (m < 1 || m > 12) throw new IllegalArgumentException("Invalid month");
        if (y < 2024)         throw new IllegalArgumentException("Card expired");
    }
}

Berbagai Pola Konstruktor Ringkas

Pola validasi umum yang digunakan dalam konstruktor ringkas.

record Percentage(double value) {
    Percentage {
        if (value < 0 || value > 100)
            throw new IllegalArgumentException(
                "Percentage must be 0-100, got: " + value);
        value = Math.round(value * 100.0) / 100.0; // round to 2 dp
    }

    public double asFraction() { return value / 100.0; }
}

Percentage tax = new Percentage(8.756);
System.out.println(tax.value());       // 8.76
System.out.println(tax.asFraction()); // 0.0876

Konstruktor Non-Kanonis

Record dapat memiliki konstruktor tambahan, tetapi konstruktor tersebut harus mendelegasikan tugas ke konstruktor kanonis menggunakan this(...).

record Point(double x, double y) {
    // Non-canonical constructor: origin point
    Point() { this(0.0, 0.0); }

    // Non-canonical: polar coordinates
    static Point fromPolar(double r, double theta) {
        return new Point(r * Math.cos(theta), r * Math.sin(theta));
    }

    public double distance(Point other) {
        double dx = this.x - other.x;
        double dy = this.y - other.y;
        return Math.sqrt(dx*dx + dy*dy);
    }
}

Point origin = new Point();
Point p = Point.fromPolar(5, Math.PI/4);
System.out.printf("Distance: %.2f%n", origin.distance(p)); // 5.00

Record Koleksi yang Tidak Dapat Diubah

Record yang menyimpan snapshot preferensi pengguna yang tidak dapat diubah serta memvalidasi dan menormalisasi data saat konstruksi.

import java.util.*;

record UserPreferences(String theme, Set<String> enabledFeatures, int fontSize) {
    private static final Set<String> VALID_THEMES = Set.of("light", "dark", "system");
    private static final Set<String> VALID_FEATURES = Set.of("ai", "beta", "analytics");

    UserPreferences {
        if (!VALID_THEMES.contains(theme))
            throw new IllegalArgumentException("Unknown theme: " + theme);
        if (!VALID_FEATURES.containsAll(enabledFeatures))
            throw new IllegalArgumentException("Unknown feature in: " + enabledFeatures);
        if (fontSize < 10 || fontSize > 24)
            throw new IllegalArgumentException("fontSize must be 10-24");
        enabledFeatures = Set.copyOf(enabledFeatures); // defensive copy
    }
}

Keterbatasan Konstruktor Ringkas

Hal-hal yang tidak dapat Anda lakukan dalam konstruktor ringkas:

  • Anda tidak dapat menetapkan komponen secara eksplisit (komponen ditetapkan secara otomatis setelah blok selesai)
  • Anda tidak dapat memanggil this() atau super()
  • Melemparkan pengecualian akan mencegah semua komponen ditetapkan
record Safe(int value) {
    Safe {
        // CAN: validate and modify component variables
        if (value < 0) value = 0; // normalized to 0 if negative
        // value = this.value; // NOT NEEDED — assignment happens after block
    }
}

System.out.println(new Safe(-5).value());  // 0 (normalized)
System.out.println(new Safe(10).value());  // 10

Pemeriksaan Singkat

Dalam konstruktor ringkas, apa yang terjadi pada perubahan yang Anda lakukan terhadap variabel komponen?

Rangkuman: Konstruktor Ringkas dan Validasi

Hal-hal penting:

  • Konstruktor ringkas dijalankan sebelum komponen ditetapkan — tidak perlu melakukan penetapan secara eksplisit
  • Gunakan konstruktor ringkas untuk memvalidasi, menormalisasi, atau menyalin komponen secara defensif
  • Ubah variabel komponen untuk menormalisasi nilai (menjadikan huruf kecil, memangkas spasi, dan menyalin)
  • Lemparkan IllegalArgumentException untuk data yang tidak valid guna menegakkan invarian
  • Gunakan List.copyOf / Set.copyOf untuk komponen koleksi yang dapat diubah
  • Konstruktor non-kanonis harus mendelegasikan tugas ke konstruktor kanonis dengan this(...)

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Konstruktor Ringkas dan Validasi” gratis?

Ya — teks lengkap “Konstruktor Ringkas dan Validasi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Konstruktor Ringkas dan Validasi”?

Tambahkan logika validasi di dalam konstruktor ringkas untuk memastikan integritas data. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Java Academy?

Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Konstruktor Ringkas dan Validasi” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Pengenalan Record
  2. Konstruktor Ringkas dan Validasi
  3. Metode Kustom pada Record
  4. Record vs Class vs Lombok
← Kembali ke Java Academy