0Pricing
Java Academy · Lektion

Kompakte Konstruktoren und Validierung

Fügen Sie Validierungslogik in kompakte Konstruktoren ein, um die Datenintegrität sicherzustellen.

Kompakte Konstruktoren und Validierung ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Kompakte Konstruktoren

Ein kompakter Konstruktor in einem Record wird ausgeführt, bevor die Komponenten zugewiesen werden. Damit können Sie Daten validieren oder normalisieren, ohne die Zuweisungen der Komponenten zu wiederholen.

Standardkonstruktor vs. kompakter Konstruktor

Der standardmäßige kanonische Konstruktor weist die Komponenten explizit zu. Beim kompakten Konstruktor entfallen Parameterliste und Zuweisungen – sie werden automatisch ausgeführt, nachdem der Rumpf durchlaufen wurde.

// 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
    }
}

Validierung in kompakten Konstruktoren

Kompakte Konstruktoren sind der übliche Weg, Record-Daten zu validieren. Lösen Sie frühzeitig Ausnahmen aus, um Invarianten durchzusetzen.

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()); }

Normalisierung in kompakten Konstruktoren

Sie können die Komponentenvariablen innerhalb eines kompakten Konstruktors ändern, bevor sie zugewiesen werden. Dadurch werden die Daten bei der Erstellung normalisiert.

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

Defensive Kopien

Erstellen Sie für veränderliche Komponenten wie Arrays oder Collections im kompakten Konstruktor eine defensive Kopie, um die Unveränderlichkeit zu bewahren.

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!");
}

Range-Record mit Grenzen

Ein praktischer Range-Record, der sicherstellt, dass min <= max gilt, und nützliche Hilfsmethoden bereitstellt.

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

Logik kompakter Konstruktoren verketten

Lagern Sie bei komplexen Validierungen Hilfsmethoden aus und rufen Sie sie aus dem kompakten Konstruktor auf.

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");
    }
}

Mehrere Muster für kompakte Konstruktoren

Häufig verwendete Validierungsmuster für kompakte Konstruktoren.

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

Nicht kanonische Konstruktoren

Records können zusätzliche Konstruktoren besitzen, diese müssen jedoch mithilfe von this(...) an den kanonischen Konstruktor delegieren.

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 mit unveränderlicher Collection

Ein Record, der einen unveränderlichen Snapshot von Benutzereinstellungen enthält und diese bei der Erstellung validiert und normalisiert.

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
    }
}

Einschränkungen kompakter Konstruktoren

Folgendes können Sie in einem kompakten Konstruktor nicht tun:

  • Sie können Komponenten nicht explizit zuweisen (sie werden nach dem Block automatisch zugewiesen)
  • Sie können this() oder super() nicht aufrufen
  • Das Auslösen einer Ausnahme verhindert alle Zuweisungen der Komponenten
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

Kurztest

Was geschieht mit den Änderungen an den Komponentenvariablen, die Sie in einem kompakten Konstruktor vornehmen?

Zusammenfassung: Kompakte Konstruktoren und Validierung

Die wichtigsten Erkenntnisse:

  • Kompakte Konstruktoren werden vor der Zuweisung der Komponenten ausgeführt – explizite Zuweisungen sind nicht erforderlich
  • Verwenden Sie sie, um Komponenten zu validieren, zu normalisieren oder defensiv zu kopieren
  • Ändern Sie Komponentenvariablen, um Werte zu normalisieren (Kleinschreibung, Entfernen von Leerzeichen, Kopieren)
  • Lösen Sie bei ungültigen Daten IllegalArgumentException aus, um Invarianten durchzusetzen
  • Verwenden Sie List.copyOf / Set.copyOf für veränderliche Collection-Komponenten
  • Nicht kanonische Konstruktoren müssen mit this(...) an den kanonischen delegieren

Häufig gestellte Fragen

Ist die Lektion „Kompakte Konstruktoren und Validierung“ kostenlos?

Ja — der vollständige Text von „Kompakte Konstruktoren und Validierung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Kompakte Konstruktoren und Validierung“?

Fügen Sie Validierungslogik in kompakte Konstruktoren ein, um die Datenintegrität sicherzustellen. Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.

Wie lange dauert die Lektion „Kompakte Konstruktoren und Validierung“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Records kennenlernen
  2. Kompakte Konstruktoren und Validierung
  3. Eigene Methoden in Records
  4. Records vs. Klassen vs. Lombok
← Zurück zu Java Academy