record
Podstawa https://openjdk.java.net/jeps/359
record
(rekord) jest nowym słowem kluczowym. Podobnie jak enum
(wyliczenie) oznacza klasę o ograniczonych możliwościach, podlegającą pewnym regułom.
Założeniem jest utworzenie prostej klasy, będącej agregatem danych.
record
ma nazwę i opis:
record Point(double x, double y){};
Powyższy kod oznacza utworzenie klasy, która:
- ma prywatne pola
double x
idouble y
oznaczone jakofinal
- ma dwie metody odczytujące
x()
iy()
. Te metody nie są getters’ami w rozumieniu JavaBean - ma publiczny konstruktor, który niejawnie ustawia wartość
this.x
ithis.y
odpowiednio nax
iy
- metodę
equals
oznaczoną jakofinal
- metodę
hashCode
oznaczoną jakofinal
- metodę
toString
- Ze względu na oznaczenia
final
klasa jest niezmienna (immutable
) i żadna klasa nie może po niej dziedziczyć. Więcej o immutable. - Rekord rozszerza klasę
java.lang.Record
, a więc nie może rozszerzać żadnej innej klasy
Poza powyższymi ograniczeniami rekordy zachowują się jak normalne klasy:
- Mogą być klasami najwyższego poziomu (top level) albo zagnieżdżonymi (nested)
- Mogą być uogólnione (generic)
- Mogą implementować interfejsy
- Instancje są tworzone przy użyciu słowa kluczowego
new
- Mogą mieć dostęp publiczny (
public
) albo chroniony
W ciele rekordu można deklarować statyczne pola, statyczne metody, statyczne inicjalizatory, konstruktory, metody instancji, typy zagnieżdżone.
Rekordy i poszczególne komponenty rekordu mogą być oznaczane adnotacjami.
Zagnieżdżony rekord jest niejawnie static
.
Komponenty klasy, które są niejawnie tworzone mogą też być tworzone jawnie.
Stosowne zmiany zostały dokonane w Reflection API.
Rekord implementujący Serializable
jest serializowany i deserializowany nieco inaczej niż inne klasy. Szczegóły omówione są w opisie klasy java.lang.Record
oraz w opisie klasy java.io.ObjectInputStream
.
Na razie jest to cecha oznaczona jako preview.
Rekord Point
package java14changes; record Point(double x, double y) { }
Klasa MainPoint
package java14changes; public class MainPoint { public static void main(String[] args){ Point point = new Point(17.0, 18.0); System.out.println(point); } }
Na konsoli zobaczymy:
Point[x=17.0, y=18.0]
Klasa Geometry
package java14changes; public class Geometry { record Point2D(double x, double y){} }
Klasa MainGeometry
package java14changes; public class MainGeometry { public static void main(String[] args){ Geometry.Point2D point = new Geometry.Point2D(0.0,0.0); System.out.println(point); } }
Na konsoli zobaczymy:
Point2D[x=0.0, y=0.0]
Struktura wewnętrzna rekordu Point
package java14changes; final class Point extends java.lang.Record { private final double x; private final double y; public Point(double x, double y) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public double x() { /* compiled code */ } public double y() { /* compiled code */ } }
Struktura wewnętrzna klasy Geometry
package java14changes; public class Geometry { public Geometry() { /* compiled code */ } static final class Point2D extends java.lang.Record { private final double x; private final double y; public Point2D(double x, double y) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public double x() { /* compiled code */ } public double y() { /* compiled code */ } } }