In this article
Ihre Java-Anwendung mit Records verbessern
Records sind ein neues Sprachfeature in Java, das mit JDK 16 eingeführt wurde. Sie sollen die Erstellung datenorientierter Klassen vereinfachen, die hauptsächlich als Datencontainer dienen. Anders gesagt: Records ermöglichen es, kompakt eine Klasse zu deklarieren, die Daten einfach speichern und kein komplexes Verhalten abbilden soll.
Records bieten eine kompakte Syntax für die Deklaration von Klassen, die hauptsächlich unveränderliche Daten enthalten. Dadurch wird der Boilerplate-Code reduziert, der bei solchen Klassen erforderlich ist. So lassen sich Datenklassen einfacher, schneller und mit weniger Fehlern erstellen und warten.
Hier ein Beispiel für einen einfachen Record, der einen Punkt im zweidimensionalen Raum darstellt:
```java
record Point(int x, int y) { }
```Diese eine Codezeile generiert automatisch einen Konstruktor, Accessor-Methoden für die Felder sowie equals()-, hashCode()- und toString()-Methoden mit dem passenden Verhalten. So reduziert sich der Code, den Sie schreiben und warten müssen.
Wie Records die Anwendungssicherheit und Softwareentwicklung verbessern
Records bieten mehrere Vorteile:
Unveränderlichkeit
Eine der wichtigsten Eigenschaften von Records ist, dass sie standardmäßig unveränderlich sind. Der Zustand unveränderlicher Objekte lässt sich nach ihrer Erstellung nicht mehr ändern. Das ist für die Sicherheit wichtig, denn dadurch sinkt die Wahrscheinlichkeit unbefugter Änderungen an den im Record gespeicherten Daten. Angreifer können Schwachstellen, die mit einem veränderlichen Zustand zusammenhängen, somit schwerer ausnutzen.
Unveränderlichkeit bietet auch Vorteile bei der Softwareentwicklung: Sie erleichtert es, Code nachzuvollziehen, und kann die Leistung nebenläufigen Codes verbessern, da weniger Synchronisierung erforderlich ist.
Weniger Boilerplate-Code
Records reduzieren Boilerplate-Code, indem sie Methoden wie equals(), hashCode() und toString() automatisch generieren. Das macht den Code kompakter und leichter lesbar. Gleichzeitig sinkt das Risiko, bei der Implementierung dieser Methoden Fehler oder Schwachstellen einzuführen.
Ein häufiges Sicherheitsproblem bei der Methode equals() ist beispielsweise das Risiko eines Timing-Angriffs beim Vergleich sensibler Daten wie kryptografischer Schlüssel. Durch den Einsatz von Records und den automatisch generierten Methoden können Entwickler dieses Risiko vermeiden.
Kapselung
Records fördern gute Kapselungspraktiken, da Entwickler die Felder in der Deklaration des Records angeben müssen. Dadurch ist klar ersichtlich, welche Daten der Record enthalten soll. Außerdem sind die Felder final und private, was das Risiko eines unbefugten Zugriffs oder einer unbefugten Änderung der Daten verringert.
Darüber hinaus generieren Records automatisch Accessor-Methoden für die Felder. Bei Bedarf können Sie damit zusätzliche Sicherheitsprüfungen oder Validierungslogik durchsetzen.
Zusammenfassend bieten Records in Java Entwicklern eine kompakte und sichere Möglichkeit, datenorientierte Klassen zu erstellen, die weniger anfällig für Schwachstellen und einfacher zu warten sind. Mit den Vorteilen der Unveränderlichkeit, weniger Boilerplate-Code und Kapselung können Records die allgemeine Sicherheit und Qualität Ihrer Java-Anwendungen verbessern.
Vergleich mit herkömmlichen Java-Klassen
Vor der Einführung von Records erforderte die Erstellung einer einfachen Datenübertragungsklasse in Java viel Boilerplate-Code. Eine herkömmliche Implementierung der Klasse Point könnte zum Beispiel so aussehen:
```java
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Point other = (Point) obj;
return x == other.x && y == other.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}
```
Wie Sie sehen, ist die herkömmliche Java-Klassenimplementierung deutlich umfangreicher als das entsprechende Java Record. Mit Records können sich Entwickler auf die wesentlichen Daten konzentrieren, die ihre Klassen enthalten müssen, und weniger Zeit mit Boilerplate-Code verbringen. Das Ergebnis ist saubererer, wartungsfreundlicherer und sichererer Code – entscheidend für die Anwendungssicherheit und bewährte Praktiken in der Softwareentwicklung.
Zusammenfassend bieten Java Records eine kompakte und sichere Möglichkeit, einfache Datenübertragungsklassen zu erstellen. Sie reduzieren Boilerplate-Code und verbessern die Lesbarkeit und Wartungsfreundlichkeit des Codes. Wenn Sie Records für Ihre Datenübertragungsobjekte verwenden, können Sie die allgemeine Sicherheit und Qualität Ihrer Java-Anwendungen verbessern.
Vorteile von Java Records
Einfacherer Code
In diesem Abschnitt erfahren Sie, wie Java Records Ihren Code einfacher und lesbarer machen können. Records bieten eine kompakte Möglichkeit, Klassen zu modellieren, die in Java ausschließlich Daten enthalten. Dadurch lässt sich Ihre Codebasis einfacher warten und verstehen. Das ist besonders im Kontext der Anwendungssicherheit wichtig, denn komplexer Code kann zu Schwachstellen führen und es erschweren, potenzielle Probleme zu erkennen und zu beheben.
Kompakte Syntax von Records
Java Records wurden in JDK 14 als Preview-Feature eingeführt und sind seit JDK 16 ein Standardfeature. Sie bieten eine kompakte Möglichkeit, einfache Klassen zu definieren, die Daten enthalten sollen. Mit Records können Entwickler Boilerplate-Code reduzieren und die Lesbarkeit des Codes verbessern. Sehen wir uns ein Beispiel an.
Betrachten wir eine einfache Klasse Person ohne Records:
```java
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
```Sehen wir uns nun an, wie sich dieselbe Klasse Person mit Records darstellen lässt:
```java
public record Person(String name, int age) {}
```Wie Sie sehen, ist die Syntax von Records deutlich kompakter und leichter lesbar. Damit sind sie ein wertvolles Werkzeug, um Code einfacher und lesbarer zu gestalten.
Automatische Generierung gängiger Methoden
Ein weiterer Vorteil von Java Records ist die automatische Generierung gängiger Methoden wie equals(), hashCode() und toString(). Diese Methoden sind unverzichtbar, um Objekte zu vergleichen und ihre Inhalte in einem für Menschen lesbaren Format anzuzeigen.
Bei herkömmlichen Klassen müssen Entwickler diese Methoden häufig manuell implementieren. Das kostet Zeit und ist fehleranfällig. Records hingegen generieren die Methoden automatisch anhand der in der Record-Definition angegebenen Komponenten.
Sehen wir uns an, welche Vorteile das für unser Beispiel mit Person hat.
Für eine herkömmliche Klasse Person könnten Sie die Methoden equals() und hashCode() wie folgt implementieren:
```java
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
```Und die Methode toString() so:
```java
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
```Bei einem Record müssen Sie diese Methoden jedoch nicht manuell implementieren. Dieselbe Funktionalität wird für unseren Person-Record automatisch generiert:
```java
public record Person(String name, int age) {}
```Die automatische Generierung gängiger Methoden reduziert Boilerplate-Code und verbessert die Lesbarkeit. So können Entwickler eine sichere und effiziente Codebasis leichter warten.
Zusammenfassend bieten Java Records eine kompakte und lesbare Möglichkeit, Klassen zu definieren, die ausschließlich Daten enthalten. Sie reduzieren Boilerplate-Code und verbessern die allgemeine Wartungsfreundlichkeit Ihrer Anwendung. Mit den Vorteilen von Records können Entwickler sichereren und effizienteren Code erstellen und so letztlich die allgemeine Sicherheitslage Ihrer Anwendung verbessern.
Bessere Lesbarkeit und Wartungsfreundlichkeit
Einer der wichtigsten Vorteile von Java Records ist, dass sie die Lesbarkeit und Wartungsfreundlichkeit Ihres Codes verbessern können. Records generieren automatisch kompakte und standardisierte Implementierungen gängiger Methoden wie equals(), hashCode() und toString(). Dadurch wird Boilerplate-Code reduziert und möglichen Fehlern und Inkonsistenzen vorgebeugt.
Betrachten Sie das folgende Beispiel einer herkömmlichen Java-Klasse:
```java
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
@Override
public boolean equals(Object obj) {
// ... implementation ...
}
@Override
public int hashCode() {
// ... implementation ...
}
@Override
public String toString() {
// ... implementation ...
}
}
```Vergleichen Sie diese nun mit dem entsprechenden Java Record:
```java
public record Point(int x, int y) {}
```Wie Sie sehen, ist die Record-Version deutlich kürzer, leichter lesbar und weniger fehleranfällig.
Unveränderlichkeit und Sicherheit
Unveränderlichkeit ist ein wichtiger Aspekt der Anwendungssicherheit. Unveränderliche Objekte lassen sich nach ihrer Erstellung nicht mehr ändern. Das hilft, verschiedene Sicherheitsprobleme wie unbefugte Datenmanipulation und Race Conditions zu verhindern.
Java Records sind von Natur aus unveränderlich, da ihr Zustand durch finale Felder definiert wird, die den Record-Komponenten entsprechen. Sobald ein Record-Objekt erstellt wurde, lässt sich sein Zustand also nicht mehr ändern. Damit sind Records eine sichere Wahl für die Modellierung Ihrer Daten.
```java
public final class ImmutablePerson {
private final String firstName;
private final String lastName;
public ImmutablePerson(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
```Unbeabsichtigte Datenmanipulation verhindern
Unveränderlichkeit bietet einen wirksamen Schutz vor unbeabsichtigter Datenmanipulation oder -beschädigung. Der Zustand eines unveränderlichen Objekts kann weder durch externen Code noch durch böswillige Akteure geändert werden. So werden unbefugte Änderungen an den Objektdaten verhindert und die Integrität des Anwendungszustands gewahrt.
Stellen Sie sich eine Anwendung vor, die sensible Nutzerdaten verwaltet. Werden diese Daten in veränderlichen Objekten gespeichert, könnte ein Angreifer möglicherweise unbefugten Zugriff erlangen und sie ändern. Mit unveränderlichen Objekten können Sie solche Angriffe verhindern, da sich ihr Zustand nicht ändern lässt.
```java
public class SensitiveData {
private final ImmutablePerson owner;
private final String secret;
public SensitiveData(ImmutablePerson owner, String secret) {
this.owner = owner;
this.secret = secret;
}
public ImmutablePerson getOwner() {
return owner;
}
public String getSecret() {
return secret;
}
}
```Angriffsfläche für Schwachstellen reduzieren
Unveränderliche Objekte verringern die Angriffsfläche einer Java-Anwendung, indem sie die Möglichkeiten für Angriffe auf den Code einschränken. Bei einem unveränderlichen Objekt gibt es weniger Einstiegspunkte, über die ein Angreifer den Anwendungszustand manipulieren kann.
Bei herkömmlichen veränderlichen Objekten ist jede Setter-Methode und jedes öffentliche Feld ein potenzieller Angriffspunkt. Wenn Sie diese Methoden und Felder entfernen, sinkt das Risiko erheblich, dass unbefugte Änderungen an den Anwendungsdaten eine Sicherheitslücke verursachen.
Java Records, eingeführt mit JDK 16, bieten eine einfache Möglichkeit, unveränderliche Datenklassen mit minimalem Boilerplate-Code zu erstellen. Records sind implizit final und ihre Felder unveränderlich. Sie generieren automatisch Konstruktoren, Accessor-Methoden sowie equals()-, hashCode()- und toString()-Methoden anhand der deklarierten Felder.
```java
public record ImmutablePersonRecord(String firstName, String lastName) { }
```Dieser Record entspricht der zuvor definierten Klasse ImmutablePerson und bietet den zusätzlichen Vorteil, dass weniger Boilerplate-Code erforderlich ist.
Zusammenfassend ist Unveränderlichkeit ein leistungsfähiges Konzept, das die Sicherheit und Resilienz Ihrer Java-Anwendungen deutlich verbessern kann. Unveränderliche Objekte können unbeabsichtigte Datenmanipulation verhindern, die Angriffsfläche reduzieren und die Integrität des Anwendungszustands gewährleisten. Nutzen Sie Java Records oder andere Techniken, um Unveränderlichkeit in Ihren Java-Anwendungen umzusetzen und deren Sicherheitslage zu verbessern.
Höhere Leistung
Records können die Leistung Ihrer Anwendung verbessern, weil sie einfach und unveränderlich sind. Unveränderlichkeit ermöglicht verschiedene Optimierungen, zum Beispiel das Zwischenspeichern der Ergebnisse aufwendiger Berechnungen oder einen geringeren Synchronisierungsbedarf in Multithreading-Umgebungen.
Darüber hinaus bieten Records eine effizientere Implementierung der Methoden equals(), hashCode() und toString(). Das kann die Leistung verbessern, wenn diese Methoden häufig verwendet werden, etwa in Collections oder Datenverarbeitungspipelines.
Weniger Boilerplate-Code
Java Records sind ein neues, mit JDK 14 eingeführtes Feature, das die Erstellung von Datenklassen vereinfacht. Mit Records müssen Sie keinen Boilerplate-Code für Getter- und Setter-Methoden sowie für die Methoden equals(), hashCode() und toString() mehr schreiben. Records generieren diese Methoden automatisch anhand der angegebenen Eigenschaften.
Um zu zeigen, wie sich Boilerplate-Code reduzieren lässt, erstellen wir zunächst eine einfache Klasse Person mit herkömmlichem Java und anschließend dieselbe Klasse als Record.
**Herkömmliche Java-Klasse:**
```java
public class Person {
private final String firstName;
private final String lastName;
private final int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
// ... implementation here
}
@Override
public int hashCode() {
// ... implementation here
}
@Override
public String toString() {
// ... implementation here
}
}
```**Record-Version:**
```java
public record Person(String firstName, String lastName, int age) {}
```Wie Sie sehen, ist die Record-Version der Klasse Person deutlich kompakter und leichter lesbar. Das verbessert nicht nur die Lesbarkeit Ihres Codes, sondern verringert auch das Risiko von Fehlern, die beim manuellen Schreiben von Boilerplate-Code entstehen können.
Optimierte Speichernutzung
Ein weiterer Leistungsvorteil von Records ist die optimierte Speichernutzung. Da Records unveränderlich sind und ihre Eigenschaften final sind, kann die JVM die Speichernutzung effizienter optimieren. Das ist besonders hilfreich, wenn Sie viele Instanzen einer Klasse verwenden und den Speicherbedarf minimieren möchten.
Angenommen, Sie haben eine Anwendung, die eine Liste von Person-Objekten verarbeitet. Bei einer herkömmlichen Java-Klasse wird für jedes Person-Objekt Speicherplatz für die Eigenschaften firstName, lastName und age belegt.
Bei der Verwendung eines Records kann die JVM den Speicherbedarf jedoch optimieren, indem sie Eigenschaften zwischen Instanzen mit denselben Werten gemeinsam nutzt. Das kann zu erheblichen Speichereinsparungen führen, wenn mehrere Objekte dieselben Eigenschaftswerte haben.
Da Records unveränderlich sind, ermöglichen sie außerdem eine effizientere Speichernutzung in Szenarien mit nebenläufiger Programmierung.
Zusammenfassend lässt sich sagen: Java Records sind ein leistungsstarkes Feature, mit dem Sie die Performance Ihrer Java-Anwendungen verbessern können, indem Sie Boilerplate-Code reduzieren und die Speichernutzung optimieren. Wenn Sie Records in Ihren Projekten einsetzen, schreiben Sie übersichtlicheren, besser wartbaren Code und erzielen eine höhere Anwendungs-Performance.
Einfache Integration in vorhandenen Code
Java Records sind für die nahtlose Zusammenarbeit mit vorhandenem Java-Code und bestehenden Bibliotheken konzipiert. Sie können Records daher schrittweise in Ihre Anwendung einführen, ohne sie umfassend umschreiben oder neu architekturieren zu müssen. Vorhandene Klassen lassen sich problemlos in Records umwandeln. Records können wie jedes andere Java-Objekt als Methodenargumente, Rückgabewerte oder in Datenstrukturen verwendet werden.
Java Records in Ihrer Anwendung verwenden
Entwicklungsumgebung einrichten
Damit Sie Ihre Java-Anwendung mit Records verbessern können, richten Sie zunächst Ihre Entwicklungsumgebung korrekt ein. In diesem Abschnitt behandeln wir die erforderliche JDK-Version und die IDE-Unterstützung für Java Records.
Erforderliche JDK-Version
Java Records wurden in JDK 14 als Preview-Feature eingeführt und in JDK 16 finalisiert. Für die Verwendung von Java Records muss daher mindestens JDK 16 auf Ihrem System installiert sein. Sie können es von der [offiziellen Oracle-Website](https://www.oracle.com/java/technologies/javase-jdk16-downloads.html) herunterladen.
Um die installierte JDK-Version zu überprüfen, öffnen Sie ein Terminal oder die Eingabeaufforderung und führen Sie folgenden Befehl aus:
```sh
java -version
```Achten Sie darauf, dass die Ausgabe JDK 16 oder höher anzeigt. Wenn mehrere JDK-Versionen installiert sind, können Sie die Umgebungsvariable JAVA_HOME auf das Installationsverzeichnis von JDK 16 setzen.
IDE-Unterstützung für Java Records
Die meisten modernen IDEs unterstützen Java Records. Im Folgenden finden Sie die Schritte zur Konfiguration einiger beliebter IDEs für Java Records:
IntelliJ IDEA
IntelliJ IDEA unterstützt Java Records ab Version 2020.1. Stellen Sie sicher, dass die neueste Version von IntelliJ IDEA installiert ist. Führen Sie folgende Schritte aus, um das JDK in IntelliJ IDEA zu konfigurieren:
1. Öffnen Sie IntelliJ IDEA und erstellen Sie ein neues Projekt oder öffnen Sie ein vorhandenes.
2. Gehen Sie zu File > Project Structure.
3. Klicken Sie im Bereich Project Settings auf Project.
4. Stellen Sie für Project SDK JDK 16 oder höher ein. Falls die Version nicht verfügbar ist, klicken Sie auf New... und wählen Sie das Installationsverzeichnis von JDK 16 aus.
5. Stellen Sie für Project language level die Option 16 - Records, sealed types, patterns, local enums, and interfaces ein.
6. Klicken Sie auf OK, um die Änderungen zu speichern.
IntelliJ IDEA ist jetzt für die Arbeit mit Java Records konfiguriert.
Eclipse
Eclipse unterstützt Java Records ab Version 4.16 (2020-06). Stellen Sie sicher, dass die neueste Version von Eclipse installiert ist. Führen Sie folgende Schritte aus, um das JDK in Eclipse zu konfigurieren:
1. Öffnen Sie Eclipse und erstellen Sie ein neues Java-Projekt oder öffnen Sie ein vorhandenes.
2. Klicken Sie im Package Explorer mit der rechten Maustaste auf das Projekt und wählen Sie Properties aus.
3. Klicken Sie im Bereich Java Build Path auf die Registerkarte Libraries.
4. Klicken Sie auf Add Library..., wählen Sie JRE System Library aus und klicken Sie auf Next.
5. Wählen Sie Workspace default JRE und anschließend JDK 16 oder höher aus der Dropdown-Liste aus. Klicken Sie auf Finish.
6. Stellen Sie im Bereich Java Compiler für Compiler compliance level den Wert 16 ein.
7. Klicken Sie auf Apply and Close, um die Änderungen zu speichern.
Eclipse ist jetzt für die Arbeit mit Java Records konfiguriert.
Visual Studio Code
Visual Studio Code unterstützt Java Records über die Erweiterung [Language Support for Java(TM) by Red Hat](https://marketplace.visualstudio.com/items?itemName=redhat.java). Stellen Sie sicher, dass die neueste Version von Visual Studio Code und die Java-Erweiterung installiert sind. Führen Sie folgende Schritte aus, um das JDK in Visual Studio Code zu konfigurieren:
1. Öffnen Sie Visual Studio Code und erstellen Sie ein neues Java-Projekt oder öffnen Sie ein vorhandenes.
2. Drücken Sie Ctrl+Shift+P (oder unter macOS Cmd+Shift+P), um die Befehlspalette zu öffnen.
3. Geben Sie Java: Configure Java Runtime ein und drücken Sie die Eingabetaste.
4. Klicken Sie im Bereich Java Tooling Runtime auf JDK und wählen Sie JDK 16 oder höher aus der Dropdown-Liste aus.
5. Starten Sie Visual Studio Code neu, damit die Änderungen übernommen werden.
Visual Studio Code ist jetzt für die Arbeit mit Java Records konfiguriert.
Nachdem Sie Ihre Entwicklungsumgebung eingerichtet haben, können Sie Java Records verwenden, um die Lesbarkeit, Unveränderlichkeit und Sicherheit Ihrer Java-Anwendung zu verbessern.
Einen Record erstellen
In diesem Abschnitt behandeln wir die grundlegende Syntax und Struktur von Java Records und zeigen anhand eines Codebeispiels, wie Sie eine einfache Record-Deklaration erstellen. Records sind ein praktisches Feature, das in Java 14 als Preview-Feature eingeführt und in Java 16 finalisiert wurde. Sie vereinfachen die Erstellung von Datenklassen. Ein Record ist im Wesentlichen eine Klasse, die unveränderliche Daten mit minimalem Boilerplate-Code speichert.
Grundlegende Syntax und Struktur
Die grundlegende Syntax für die Deklaration eines Records in Java lautet:
```java
record RecordName (Type1 field1, Type2 field2, ..., TypeN fieldN) {
// Additional methods and logic can be added here
}
```Eine Record-Deklaration besteht aus dem Schlüsselwort record, gefolgt vom Namen des Records und einer Liste von Feldern in Klammern. Die Felder werden mit den jeweiligen Typen und Namen, durch Kommas getrennt, deklariert. Der Record-Rumpf in geschweiften Klammern kann bei Bedarf zusätzliche Methoden und Logik enthalten.
Sehen wir uns die wichtigsten Eigenschaften von Records an:
1. Records sind standardmäßig unveränderlich. Das bedeutet, dass sich die Feldwerte nach dem Erstellen einer Record-Instanz nicht mehr ändern lassen.
2. Die Felder eines Records sind final und können daher nicht geändert werden.
3. Records generieren automatisch Standardimplementierungen für folgende Methoden: equals(), hashCode(), toString() sowie die Zugriffsmethoden (Getter) für jedes Feld.
4. Records können zusätzliche Methoden und Logik enthalten, aber keine veränderlichen Instanzfelder.
Codebeispiel: Einfache Record-Deklaration
In diesem Beispiel erstellen wir eine einfache Deklaration für den Record Person mit drei Feldern: firstName, lastName und age.
```java
public record Person(String firstName, String lastName, int age) {
// Additional methods and logic can be added here, if needed
}
```Erstellen wir nun eine Instanz des Records Person und sehen uns an, wie die automatisch generierten Methoden funktionieren:
```java
public class Main {
public static void main(String[] args) {
Person person = new Person("John", "Doe", 30);
// Accessor methods (getters) are automatically generated
String firstName = person.firstName();
String lastName = person.lastName();
int age = person.age();
// Default implementation of toString()
System.out.println(person); // Output: Person[firstName=John, lastName=Doe, age=30]
// Default implementation of equals()
Person person2 = new Person("John", "Doe", 30);
System.out.println(person.equals(person2)); // Output: true
}
}
```Wie Sie sehen, konnten wir eine einfache Record-Deklaration mit minimalem Boilerplate-Code erstellen. Die generierten Zugriffsmethoden sowie die Methoden toString() und equals() funktionieren wie erwartet.
Zusammenfassend bieten Java Records eine prägnante und praktische Möglichkeit, unveränderliche Datenklassen mit minimalem Codeumfang zu erstellen. Mit Records verbessern Sie die Lesbarkeit und Wartbarkeit Ihrer Java-Anwendungen und erhöhen zugleich ihre Sicherheit, da die Daten unveränderlich sind.
Methoden und Validierung zu Records hinzufügen
Java Records, die in JDK 16 eingeführt wurden, bieten eine neue Möglichkeit, einfache und prägnante Datenklassen zu erstellen, die auf das Speichern veränderlicher Daten ausgerichtet sind. Records sind zwar in erster Linie für unveränderliche Daten und einfache Zugriffsmethoden konzipiert, Sie können ihnen aber dennoch eigene Methoden und Validierungslogik hinzufügen. In diesem Abschnitt erfahren Sie, wie Sie Java Records um benutzerdefinierte Methoden und Validierungslogik erweitern, um die Sicherheit und Robustheit Ihrer Anwendung zu verbessern.
Benutzerdefinierte Methoden zu Records hinzufügen
Ein Vorteil von Records ist, dass sie automatisch Zugriffsmethoden sowie equals(), hashCode() und toString() generieren. Für bestimmte Berechnungen oder Vorgänge mit den im Record gespeicherten Daten möchten Sie möglicherweise eigene Methoden hinzufügen. Definieren Sie die benutzerdefinierte Methode einfach im Rumpf des Records. Beachten Sie, dass diese Methoden die im Record gespeicherten Daten nicht ändern sollten, damit die Unveränderlichkeit erhalten bleibt.
Hier sehen Sie ein Beispiel für eine benutzerdefinierte Methode in einem Record:
```java
record Employee(String name, int age, double salary) {
public double calculateYearlyBonus() {
return salary * 0.1;
}
}
```In diesem Beispiel haben wir dem Record Employee die benutzerdefinierte Methode calculateYearlyBonus() hinzugefügt. Diese Methode berechnet den Jahresbonus auf Grundlage des Gehalts der betreffenden Person.
Codebeispiel: Validierung zu einem Record hinzufügen
Die Validierung eines Records ist wichtig, um sicherzustellen, dass die darin gespeicherten Daten gültig und sicher sind. Sie kann dazu beitragen, Sicherheitslücken wie Datenmanipulation oder Injection-Angriffe zu verhindern. Für die Validierung eines Records können Sie den kompakten Konstruktor verwenden. Damit lässt sich ein Konstruktor für einen Record definieren, ohne die Parameter explizit anzugeben.
Hier sehen Sie ein Beispiel für die Validierung eines Records:
```java
record EmailAddress(String email) {
public EmailAddress {
if (email == null || email.isBlank()) {
throw new IllegalArgumentException("Email cannot be null or blank");
}
if (!isValidEmail(email)) {
throw new IllegalArgumentException("Invalid email format");
}
}
private static boolean isValidEmail(String email) {
// Use a regex pattern or a library to validate the email format
// For simplicity, we use a basic regex pattern here
String emailPattern = "^[A-Za-z0-9+_.-]+@(.+)$";
return email.matches(emailPattern);
}
}
```In diesem Beispiel haben wir den Record EmailAddress so validiert, dass die E-Mail-Adresse weder null noch leer ist und ein gültiges Format hat. Dazu haben wir einen kompakten Konstruktor für die Validierungslogik und eine private Methode isValidEmail() zur Überprüfung des E-Mail-Formats verwendet.
Mit diesen Techniken können Sie die Sicherheit und Robustheit Ihrer Java-Anwendungen verbessern, indem Sie Records um benutzerdefinierte Methoden und Validierungslogik erweitern. So stellen Sie sicher, dass die Daten Ihrer Anwendung gültig und sicher bleiben, und erhöhen ihre Gesamtqualität und Resilienz.
Records mit anderen Java-Features verwenden
Java Records, die in JDK 14 als Preview-Feature eingeführt und in JDK 16 finalisiert wurden, bringen mehr Einfachheit und Prägnanz in die Sprache. Sie eignen sich besonders für die Modellierung von Datencontainerklassen, die traditionell viel Boilerplate-Code erfordern. In diesem Abschnitt erfahren Sie, wie Sie Records mit anderen Java-Features wie Interfaces und Vererbung verwenden, um die Codesicherheit und Wartbarkeit Ihrer Java-Anwendung zu verbessern.
Records und Interfaces
Ein Record kann zwar keine andere Klasse erweitern, aber ein oder mehrere Interfaces implementieren. Dadurch können Sie Records mit etablierten Entwurfsmustern kombinieren und die Vorteile von Records und Interfaces in Ihrer Anwendung nutzen. Sehen wir uns ein einfaches Beispiel an.
Angenommen, wir haben ein Interface namens Displayable, das Objekte repräsentiert, die auf dem Bildschirm angezeigt werden können:
```java
public interface Displayable {
String display();
}
```Wir können einen Record erstellen, der dieses Interface implementiert:
```java
public record Person(String name, int age) implements Displayable {
@Override
public String display() {
return "Name: " + name + ", Age: " + age;
}
}
```In diesem Beispiel implementiert der Record Person das Interface Displayable und stellt eine konkrete Implementierung der Methode display() bereit. Dadurch kann der Record Person überall dort verwendet werden, wo ein Objekt vom Typ Displayable erwartet wird.
Records und Vererbung
Wie bereits erwähnt, können Records keine anderen Klassen erweitern. Das liegt daran, dass Records implizit final sind und von der Klasse java.lang.Record erben. Daher können sie nicht an der traditionellen Klassenvererbung teilnehmen. Über Interfaces können Records jedoch weiterhin Teil einer Typhierarchie sein, wie im vorherigen Beispiel gezeigt.
Beachten Sie, dass Records nicht als Basisklasse für andere Klassen verwendet werden sollten. Ihr Hauptzweck besteht darin, als einfache, unveränderliche Datenträger zu dienen. Werden sie um zusätzliche Funktionen erweitert, kann dies zu unbeabsichtigten Nebenwirkungen und mehr Komplexität führen.
Codebeispiel: Records mit anderen Java-Features kombinieren
Nachdem wir nun wissen, wie Records mit Interfaces und Vererbung zusammenarbeiten, sehen wir uns ein praktisches Beispiel an. Angenommen, wir arbeiten an einer Projektmanagement-Anwendung und möchten verschiedene Aufgabentypen modellieren.
Als Erstes können wir ein Interface namens Task definieren:
```java
public interface Task {
String getDescription();
int getPriority();
boolean isCompleted();
}
```Anschließend können wir für jeden Aufgabentyp einen Record erstellen, der das Interface Task implementiert:
```java
public record BugFix(String description, int priority) implements Task {
@Override
public boolean isCompleted() {
// Implement logic to determine if the bug fix is completed
}
}
public record Feature(String description, int priority) implements Task {
@Override
public boolean isCompleted() {
// Implement logic to determine if the feature is completed
}
}
```In diesem Beispiel haben wir zwei Records erstellt, BugFix und Feature, die beide das Interface Task implementieren. So lassen sich beide Aufgabentypen in unserer Projektmanagement-Anwendung einheitlich behandeln und zugleich die Vorteile von Records nutzen: Einfachheit und Unveränderlichkeit.
Priorisieren Sie, was am wichtigsten ist
Unternehmen benötigen einen ganzheitlichen Ansatz zur Risikopriorisierung. Nutzen Sie mit Snyk eine kontextbezogene, risikobasierte Priorisierung.