Java 14 a introduit une nouvelle façon de créer des classes appelées Records. Dans ce tutoriel, nous allons apprendre :
- Pourquoi avons-nous besoin de Java Records
- Comment créer des Records et les utiliser
- Surcharge et extension des classes Records
Lecture recommandée : Fonctionnalités de Java 14
Pourquoi avons-nous besoin de Java Records ?
Une des plaintes courantes concernant Java a été sa verbosité. Si vous devez créer une simple classe POJO, cela nécessite le code boilerplate suivant.
- Champs privés
- Méthodes Getter et Setter
- Constructeurs
- Méthodes hashCode(), equals(), et toString().
Cette verbosité est l’une des raisons de l’intérêt élevé pour Kotlin et Project Lombok .
En fait, la simple frustration d’écrire ces méthodes génériques à chaque fois a conduit aux raccourcis pour les créer dans les IDE Java tels que Eclipse et IntelliJ IDEA.
Voici la capture d’écran montrant l’option de l’IDE Eclipse pour générer les méthodes cérémoniales pour une classe.

Les Java Records sont destinés à supprimer cette verbosité en fournissant une structure compacte pour créer les classes POJO.
Comment créer des enregistrements Java
Les enregistrements Java sont une fonctionnalité de prévisualisation, développée dans le cadre du JEP 359. Ainsi, vous avez besoin de deux choses pour créer des enregistrements dans vos projets Java.
- JDK 14 installé. Si vous utilisez un IDE, il doit également prendre en charge Java 14. Eclipse et IntelliJ fournissent déjà un support pour Java 14, donc nous sommes bons ici.
- Activer la fonctionnalité de prévisualisation: Par défaut, les fonctionnalités de prévisualisation sont désactivées. Vous pouvez les activer dans Eclipse depuis les paramètres du compilateur Java du projet.

Vous pouvez activer les fonctionnalités de prévisualisation de Java 14 en ligne de commande en utilisant l’option --enable-preview -source 14
.
Disons que je veux créer une classe de modèle Employee. Elle ressemblera à quelque chose comme le code suivant.
package com.journaldev.java14;
import java.util.Map;
public class Employee {
private int id;
private String name;
private long salary;
private Map<String, String> addresses;
public Employee(int id, String name, long salary, Map<String, String> addresses) {
super();
this.id = id;
this.name = name;
this.salary = salary;
this.addresses = addresses;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public long getSalary() {
return salary;
}
public Map<String, String> getAddresses() {
return addresses;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((addresses == null) ? 0 : addresses.hashCode());
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + (int) (salary ^ (salary >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (addresses == null) {
if (other.addresses != null)
return false;
} else if (!addresses.equals(other.addresses))
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (salary != other.salary)
return false;
return true;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + ", addresses=" + addresses + "]";
}
}
Ouf, c’est plus de 70 lignes de code auto-généré. Voyons maintenant comment créer une classe Employee Record, qui fournit essentiellement les mêmes fonctionnalités.
package com.journaldev.java14;
import java.util.Map;
public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {
}
Wow, ça ne peut pas être plus court que ça. J’adore déjà les classes Record.
Maintenant, utilisons la commande javap
pour comprendre ce qui se passe en arrière-plan lors de la compilation d’un Record.
# javac --enable-preview -source 14 EmpRecord.java
Note: EmpRecord.java uses preview language features.
Note: Recompile with -Xlint:preview for details.
# javap EmpRecord
Compiled from "EmpRecord.java"
public final class EmpRecord extends java.lang.Record {
public EmpRecord(int, java.lang.String, long, java.util.Map<java.lang.String, java.lang.String>);
public java.lang.String toString();
public final int hashCode();
public final boolean equals(java.lang.Object);
public int id();
public java.lang.String name();
public long salary();
public java.util.Map<java.lang.String, java.lang.String> addresses();
}
#

# javac —enable–preview –source 14 EmpRecord.java
# javap EmpRecord
Si vous souhaitez plus de détails internes, exécutez la commande javap avec l’option -v.
- A Record class is final, so we can’t extend it.
- # javap -v EmpRecord
- Points importants concernant les classes Record
- Les classes Record étendent implicitement la classe
java.lang.Record
. - A single constructor is created with all the fields specified in the record definition.
- Tous les champs spécifiés dans la déclaration du record sont finaux.
- Les champs du record sont immuables « peu profonds » et dépendent du type. Par exemple, nous pouvons modifier le champ des adresses en y accédant, puis en effectuant des mises à jour.
La classe Record fournit automatiquement des méthodes d’accès pour les champs. Le nom de la méthode est le même que celui du champ, contrairement aux méthodes génériques et conventionnelles d’obtention.
La classe Record fournit également les implémentations de hashCode(), equals() et toString().
package com.journaldev.java14;
public class RecordTest {
public static void main(String[] args) {
EmpRecord empRecord1 = new EmpRecord(10, "Pankaj", 10000, null);
EmpRecord empRecord2 = new EmpRecord(10, "Pankaj", 10000, null);
Utilisation des enregistrements dans un programme Java
System.out.println(empRecord1);
Jetons un coup d'œil à un exemple simple d'utilisation de notre classe EmpRecord.
System.out.println("Name: "+empRecord1.name());
System.out.println("ID: "+empRecord1.id());
// toString()
System.out.println(empRecord1.equals(empRecord2));
// accès aux champs
System.out.println(empRecord1 == empRecord2);
}
}
// equals()
EmpRecord[id=10, name=Pankaj, salary=10000, addresses=null]
Name: Pankaj
ID: 10
true
false
// hashCode()
Sortie :
L’objet Record fonctionne de la même manière que toute classe modèle, objet de données, etc.
public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {
public EmpRecord {
if (id < 0)
throw new IllegalArgumentException("employee id can't be negative");
if (salary < 0)
throw new IllegalArgumentException("employee salary can't be negative");
}
}
Extension du constructeur Records
EmpRecord empRecord1 = new EmpRecord(-10, "Pankaj", 10000, null);
Parfois, nous voulons avoir des validations ou des journaux dans notre constructeur. Par exemple, l’identifiant de l’employé et le salaire ne doivent pas être négatifs. Le constructeur par défaut n’aura pas cette validation. Nous pouvons créer un constructeur compact dans la classe d’enregistrement. Le code de ce constructeur sera placé au début du constructeur généré automatiquement.
Exception in thread "main" java.lang.IllegalArgumentException: employee id can't be negative
at com.journaldev.java14.EmpRecord.<init>(EmpRecord.java:9)
Si nous créons un EmpRecord comme dans le code suivant :
Nous obtiendrons une exception d’exécution comme suit :
public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {
public int getAddressCount() {
if (this.addresses != null)
return this.addresses().size();
else
return 0;
}
}
Est-ce que les classes Records peuvent avoir des méthodes?
Oui, nous pouvons créer des méthodes dans les classes Records.
Mais, les classes Records sont destinées à être des porteurs de données. Il est préférable d’éviter d’avoir des méthodes utilitaires dans une classe Record. Par exemple, la méthode ci-dessus peut être créée dans une classe utilitaire.
Si vous pensez qu’avoir une méthode est indispensable pour votre classe Record, réfléchissez bien si vous avez vraiment besoin d’une classe Record?
Source:
https://www.digitalocean.com/community/tutorials/java-records-class