Ce face Record
Orice record (de exemplu record Elev(String nume, int nota)) extinde automat clasa abstractă java.lang.Record, la fel cum orice clasă obișnuită extinde Object. Nu poți scrie extends Record de mână; compilatorul nu permite.
Record declară equals, hashCode și toString ca abstracte, iar compilatorul le generează pentru fiecare record după componente: două record-uri sunt egale dacă au toate componentele egale, iar toString arată Elev[nume=Ana, nota=9].
Poți scrie metode care primesc orice record cu tipul Record, sau verifica obiect instanceof Record. Prin reflecție, getClass().isRecord() și getRecordComponents() dau numele și valorile componentelor, ceea ce bibliotecile JSON folosesc pentru a transforma record-urile automat.
Ce returnează
Nu creezi direct obiecte Record; folosești tipurile record declarate de tine.
Exemple
Exemplul 1: Orice record este un Record
public class Main {
record Elev(String nume, int nota) { }
record Oras(String nume, String judet) { }
static String descrie(Object o) {
return o instanceof Record ? "record: " + o : "obiect obișnuit: " + o;
}
public static void main(String[] args) {
System.out.println(descrie(new Elev("Ana", 9)));
System.out.println(descrie(new Oras("Iași", "IS")));
System.out.println(descrie("text"));
System.out.println("Clasa de bază: " + Elev.class.getSuperclass().getName());
}
}
Rezultat
record: Elev[nume=Ana, nota=9]
record: Oras[nume=Iași, judet=IS]
obiect obișnuit: text
Clasa de bază: java.lang.Record
Exemplul 2: equals și hashCode generate
import java.util.HashSet;
import java.util.Set;
public class Main {
record Nota(String elev, String materie, int valoare) { }
public static void main(String[] args) {
Nota a = new Nota("Ana", "mate", 9);
Nota b = new Nota("Ana", "mate", 9);
Nota c = new Nota("Ana", "fizică", 9);
System.out.println("a.equals(b): " + a.equals(b) + ", a == b: " + (a == b));
System.out.println("a.equals(c): " + a.equals(c));
System.out.println("hashCode egal: " + (a.hashCode() == b.hashCode()));
Set<Nota> note = new HashSet<>(Set.of(a, c));
note.add(b);
System.out.println("Note distincte: " + note.size());
}
}
Rezultat
a.equals(b): true, a == b: false
a.equals(c): false
hashCode egal: true
Note distincte: 2
Exemplul 3: Componentele citite prin reflecție
Metoda afiseaza funcționează pentru orice record, fără să-i cunoască tipul.
import java.lang.reflect.RecordComponent;
public class Main {
record Produs(String nume, double pret, int stoc) { }
static void afiseaza(Record r) throws ReflectiveOperationException {
System.out.println(r.getClass().getSimpleName() + " (isRecord: " + r.getClass().isRecord() + ")");
for (RecordComponent c : r.getClass().getRecordComponents()) {
System.out.println(" " + c.getName() + " : " + c.getType().getSimpleName() + " = " + c.getAccessor().invoke(r));
}
}
public static void main(String[] args) throws ReflectiveOperationException {
afiseaza(new Produs("Caiet A4", 7.5, 128));
}
}
Rezultat
Produs (isRecord: true)
nume : String = Caiet A4
pret : double = 7.5
stoc : int = 128
Greșeli frecvente
- Încerci
class Elev extends Record. Nu compilează; folosește cuvântul cheierecord. - Pui într-un record un tablou sau o listă modificabilă și te aștepți ca
equalssă compare conținutul tabloului. Pentru tablouri,equalscompară referințele; foloseșteList.ofsau scrie singurequals.
Comenzi înrudite
IllegalArgumentException: Excepția aruncată când o metodă primește un argument cu valoare nepermisă (vârstă negativă, lună 13).Object.equals: equals() spune dacă două obiecte sunt „egale”, iar hashCode() dă un număr folosit de HashMap și HashSet; se suprascriu împreună.