In this article
Améliorer votre application Java avec les Records
Les Records en Java sont une fonctionnalité du langage introduite dans JDK 16. Ils visent à simplifier la création de classes centrées sur les données, principalement destinées à servir de conteneurs. Autrement dit, les Records permettent de déclarer de manière concise une classe conçue pour contenir des données, sans comportement complexe.
Les Records offrent une syntaxe compacte pour déclarer des classes principalement destinées à stocker des données immuables, ce qui réduit le code répétitif nécessaire pour travailler avec ces classes. Il devient ainsi plus facile et plus rapide de créer et de maintenir des classes de données, tout en réduisant les risques d’erreur.
Voici un exemple de création d’un Record simple pour un point dans un espace 2D :
```java
record Point(int x, int y) { }
```Cette seule ligne de code génère automatiquement un constructeur, des accesseurs pour les champs, ainsi que les méthodes equals(), hashCode() et toString() avec le comportement approprié. Vous avez ainsi moins de code à écrire et à maintenir.
L’importance des Records pour renforcer la sécurité des applications et le développement logiciel
Les Records offrent plusieurs avantages :
Immutabilité
L’une des principales caractéristiques des Records est leur immutabilité par défaut. Les objets immuables sont des objets dont l’état ne peut pas être modifié après leur création. C’est important pour la sécurité, car cela réduit le risque de modifications non autorisées des données contenues dans le Record et complique l’exploitation des vulnérabilités liées à un état mutable.
L’immutabilité présente aussi des avantages pour le développement logiciel : elle facilite le raisonnement sur le code et peut améliorer les performances du code concurrent en réduisant le besoin de synchronisation.
Réduction du code répétitif
Les Records réduisent le code répétitif en générant automatiquement des méthodes telles que equals(), hashCode() et toString(). Le code est ainsi plus concis et plus facile à lire, et le risque d’introduire des erreurs ou des vulnérabilités lors de l’implémentation de ces méthodes diminue.
Par exemple, un problème de sécurité courant lié à la méthode equals() est le risque d’introduire une attaque par canal auxiliaire temporel lors de la comparaison de données sensibles, comme des clés cryptographiques. En utilisant les Records et leurs méthodes générées automatiquement, les développeurs peuvent éviter ce type de vulnérabilité.
Encapsulation
Les Records favorisent de bonnes pratiques d’encapsulation en obligeant les développeurs à déclarer les champs dans la déclaration du Record. Les données que le Record est destiné à contenir sont ainsi clairement définies, et les champs sont garantis finaux et privés, ce qui réduit le risque d’accès ou de modification non autorisés.
De plus, les Records génèrent automatiquement des accesseurs pour les champs. Ceux-ci peuvent servir à appliquer des contrôles de sécurité supplémentaires ou une logique de validation, si nécessaire.
En conclusion, les Records en Java offrent aux développeurs un moyen concis et sécurisé de créer des classes centrées sur les données, moins sujettes aux vulnérabilités et plus faciles à maintenir. En tirant parti de l’immutabilité, de la réduction du code répétitif et de l’encapsulation, les Records contribuent à améliorer la sécurité et la qualité globales de vos applications Java.
Comparaison avec les classes Java traditionnelles
Avant l’introduction des Records, créer en Java une simple classe servant à transporter des données nécessitait beaucoup de code répétitif. Par exemple, une implémentation traditionnelle de la classe Point ressemblerait à ceci :
```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 +
'}';
}
}
```
Comme vous pouvez le constater, l’implémentation d’une classe Java traditionnelle est bien plus longue que son équivalent sous forme de Record Java. Avec les Records, les développeurs peuvent se concentrer sur les données essentielles que leurs classes doivent transporter et consacrer moins de temps à écrire du code répétitif. Le résultat : un code plus propre, plus facile à maintenir et plus sûr, essentiel pour la sécurité des applications et les bonnes pratiques de développement logiciel.
En conclusion, les Records Java offrent un moyen concis et sécurisé de créer de simples classes de transport de données, en réduisant le code répétitif et en améliorant la lisibilité et la maintenabilité du code. En utilisant des Records pour vos objets de transfert de données, vous pouvez renforcer la sécurité et la qualité globales de vos applications Java.
Avantages des Records Java
Simplicité du code
Dans cette section, nous verrons comment les Records Java peuvent rendre votre code plus simple et plus lisible. Les Records offrent un moyen concis de modéliser en Java des classes qui ne contiennent que des données, ce qui facilite la compréhension et la maintenance de votre base de code. C’est particulièrement important pour la sécurité des applications, car un code complexe peut entraîner des vulnérabilités et compliquer la détection et la correction des problèmes potentiels.
La syntaxe concise des Records
Les Records Java ont été introduits dans JDK 14 en tant que fonctionnalité en préversion, puis sont devenus une fonctionnalité standard dans JDK 16. Ils permettent de définir simplement des classes destinées à contenir des données. En utilisant les Records, les développeurs peuvent réduire le code répétitif et améliorer la lisibilité du code. Voyons un exemple.
Prenons une classe Person simple, sans utiliser de 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;
}
}
```Voyons maintenant comment représenter la même classe Person avec un Record :
```java
public record Person(String name, int age) {}
```Comme vous pouvez le constater, la syntaxe des Records est bien plus concise et facile à lire. Ils constituent donc un outil précieux pour simplifier le code et en améliorer la lisibilité.
Génération automatique des méthodes courantes
Un autre avantage des Records Java est la génération automatique de méthodes courantes, telles que equals(), hashCode() et toString(). Ces méthodes sont indispensables pour comparer des objets et afficher leur contenu dans un format lisible.
Avec les classes classiques, les développeurs doivent souvent implémenter ces méthodes manuellement, ce qui peut prendre du temps et entraîner des erreurs. Les Records, quant à eux, génèrent automatiquement ces méthodes à partir des composants déclarés dans leur définition.
Voyons ce que cela apporte à notre exemple Person.
Pour une classe Person classique, vous pourriez implémenter les méthodes equals() et hashCode() ainsi :
```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);
}
```Et la méthode toString() ainsi :
```java
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
```Cependant, avec un Record, vous n’avez pas à implémenter ces méthodes manuellement. Les mêmes fonctionnalités sont générées automatiquement pour notre Record Person :
```java
public record Person(String name, int age) {}
```La génération automatique des méthodes courantes réduit le code répétitif et améliore sa lisibilité. Les développeurs peuvent ainsi maintenir plus facilement une base de code sécurisée et efficace.
En conclusion, les Records Java offrent un moyen concis et lisible de définir des classes qui ne contiennent que des données, en réduisant le code répétitif et en améliorant la maintenabilité globale de votre application. En tirant parti des avantages des Records, les développeurs peuvent créer un code plus sûr et plus efficace, contribuant ainsi à renforcer la posture de sécurité de votre application.
Une meilleure lisibilité et une meilleure maintenabilité
L’un des principaux avantages des Records Java est leur capacité à améliorer la lisibilité et la maintenabilité du code. Les Records génèrent automatiquement des implémentations concises et standardisées de méthodes courantes telles que equals(), hashCode() et toString(). Cela réduit le code répétitif et élimine les risques de bugs et d’incohérences.
Voici un exemple de classe Java traditionnelle :
```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 ...
}
}
```Comparons-la maintenant à l’équivalent en Record Java :
```java
public record Point(int x, int y) {}
```Comme vous pouvez le constater, la version Record est beaucoup plus courte, plus facile à lire et moins sujette aux erreurs.
Immutabilité et sécurité
L’immutabilité est un aspect essentiel de la sécurité des applications. Les objets immuables ne peuvent pas être modifiés après leur création, ce qui contribue à prévenir divers problèmes de sécurité, comme la falsification non autorisée de données et les conditions de concurrence.
Les Records Java sont intrinsèquement immuables, car leur état est défini par des champs finaux correspondant à leurs composants. Ainsi, une fois un objet Record créé, son état ne peut plus être modifié : c’est un choix sûr pour modéliser vos données.
```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;
}
}
```Prévenir la manipulation involontaire des données
L’immutabilité constitue une protection efficace contre la manipulation ou la corruption involontaire des données. L’état d’un objet immuable ne peut être modifié par du code externe ou des acteurs malveillants. Cela empêche toute modification non autorisée des données de l’objet et garantit l’intégrité de l’état de l’application.
Prenons une application qui gère des données utilisateur sensibles. Si ces données sont stockées dans des objets mutables, un attaquant pourrait potentiellement y accéder sans autorisation et les modifier. En utilisant des objets immuables, vous pouvez prévenir ce type d’attaque, car l’attaquant ne peut pas modifier leur état.
```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;
}
}
```Réduction de la surface d’attaque vulnérable
Les objets immuables contribuent à réduire la surface d’attaque d’une application Java en limitant les possibilités d’exploitation du code. Un objet immuable offre moins de points d’entrée permettant à un attaquant de manipuler l’état de l’application.
Dans les objets mutables traditionnels, chaque méthode setter ou champ public constitue un point d’attaque potentiel. En supprimant ces méthodes et ces champs, vous réduisez considérablement les risques de vulnérabilités dues à des modifications non autorisées des données de l’application.
Introduits dans JDK 16, les Records Java permettent de créer facilement des classes de données immuables avec un minimum de code répétitif. Les Records sont implicitement finaux et leurs champs sont immuables. Ils génèrent automatiquement des constructeurs, des accesseurs ainsi que les méthodes equals(), hashCode() et toString() à partir des champs déclarés.
```java
public record ImmutablePersonRecord(String firstName, String lastName) { }
```Ce Record est équivalent à la classe ImmutablePerson définie précédemment, avec moins de code répétitif.
En conclusion, l’immutabilité est un concept puissant qui peut considérablement renforcer la sécurité et la résilience de vos applications Java. Les objets immuables peuvent prévenir la manipulation involontaire des données, réduire la surface d’attaque et garantir l’intégrité de l’état de votre application. Envisagez d’utiliser les Records Java ou d’autres techniques pour adopter l’immutabilité dans vos applications Java et renforcer leur posture de sécurité.
De meilleures performances
Les Records peuvent améliorer les performances de votre application grâce à leur simplicité et à leur immutabilité. L’immutabilité permet diverses optimisations, comme la mise en cache des résultats de calculs coûteux ou la réduction du besoin de synchronisation dans un environnement multithread.
De plus, les Records offrent une implémentation plus efficace des méthodes equals(), hashCode() et toString(). Les performances peuvent ainsi être meilleures lorsque ces méthodes sont fréquemment utilisées, par exemple dans des collections ou des pipelines de traitement de données.
Réduction du code répétitif
Les Records Java sont une fonctionnalité introduite dans JDK 14 qui simplifie la création de classes de données. En utilisant les Records, vous pouvez éviter d’écrire du code répétitif, comme les méthodes getter et setter, equals(), hashCode() et toString(). Les Records génèrent automatiquement ces méthodes à partir des propriétés fournies.
Pour illustrer la réduction du code répétitif, créons une classe Person simple en Java traditionnel, puis la même classe sous forme de Record.
**Classe Java traditionnelle :**
```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
}
}
```**Version Record :**
```java
public record Person(String firstName, String lastName, int age) {}
```Comme vous pouvez le constater, la version Record de la classe Person est bien plus concise et facile à lire. Cela améliore la lisibilité du code et réduit aussi les risques de bugs dus à une erreur humaine lors de l’écriture de code répétitif.
Optimisation de l’utilisation de la mémoire
Les Records permettent également d’optimiser l’utilisation de la mémoire. Comme ils sont immuables et que leurs propriétés sont finales, la JVM peut gérer la mémoire plus efficacement. C’est particulièrement utile lorsque vous avez de nombreuses instances d’une classe et que vous souhaitez réduire leur empreinte mémoire.
Par exemple, imaginons une application qui traite une liste d’objets Person. Avec une classe Java traditionnelle, chaque objet Person disposerait d’une allocation mémoire pour stocker les propriétés firstName, lastName et age.
Toutefois, avec un record, la JVM peut optimiser l’utilisation de la mémoire en partageant les propriétés entre les instances qui ont les mêmes valeurs. Cela peut générer d’importantes économies de mémoire lorsque plusieurs objets ont les mêmes valeurs de propriété.
De plus, grâce à leur immutabilité, les records permettent une utilisation plus efficace de la mémoire dans les scénarios de programmation concurrente.
En conclusion, les records Java sont une fonctionnalité puissante qui peut améliorer les performances de vos applications Java en réduisant le code répétitif et en optimisant l’utilisation de la mémoire. En adoptant les records dans vos projets, vous pouvez écrire un code plus clair et plus facile à maintenir, tout en améliorant les performances de vos applications.
Intégration facile au code existant
Les records Java sont conçus pour fonctionner harmonieusement avec le code et les bibliothèques Java existants. Vous pouvez donc les introduire progressivement dans votre application sans réécriture ni refonte importante. Les classes existantes peuvent être facilement converties en records, et les records peuvent être utilisés comme arguments ou valeurs de retour de méthodes, ou dans des structures de données, comme n’importe quel autre objet Java.
Comment utiliser les records Java dans votre application
Configuration de votre environnement de développement
Pour commencer à améliorer votre application Java avec les records, configurez correctement votre environnement de développement. Dans cette section, nous aborderons la version du JDK requise et la prise en charge des records Java par les IDE.
Version du JDK requise
Les records Java ont été introduits en tant que fonctionnalité en préversion dans JDK 14, puis finalisés dans JDK 16. Pour utiliser les records Java, vous devez donc avoir au moins JDK 16 installé sur votre système. Vous pouvez le télécharger depuis le [site officiel d’Oracle](https://www.oracle.com/java/technologies/javase-jdk16-downloads.html).
Pour vérifier la version du JDK installé, ouvrez votre terminal ou votre invite de commandes, puis exécutez la commande suivante :
```sh
java -version
```Vérifiez que le résultat indique JDK 16 ou une version ultérieure. Si plusieurs versions du JDK sont installées, vous pouvez définir la variable d’environnement JAVA_HOME pour qu’elle pointe vers le répertoire d’installation de JDK 16.
Prise en charge des records Java par les IDE
La plupart des IDE modernes prennent en charge les records Java. Voici comment configurer certains IDE populaires pour utiliser les records Java :
IntelliJ IDEA
IntelliJ IDEA prend en charge les records Java depuis la version 2020.1. Assurez-vous d’avoir installé la dernière version d’IntelliJ IDEA. Pour configurer le JDK dans IntelliJ IDEA, procédez comme suit :
1. Ouvrez IntelliJ IDEA et créez un projet, ou ouvrez-en un existant.
2. Accédez à File > Project Structure.
3. Dans la section Project Settings, cliquez sur Project.
4. Définissez Project SDK sur JDK 16 ou une version ultérieure. Si cette option n’est pas disponible, cliquez sur New..., puis sélectionnez le répertoire d’installation de JDK 16.
5. Définissez Project language level sur 16 - Records, sealed types, patterns, local enums, and interfaces.
6. Cliquez sur OK pour enregistrer les modifications.
IntelliJ IDEA est maintenant configuré pour fonctionner avec les records Java.
Eclipse
Eclipse prend en charge les records Java depuis la version 4.16 (2020-06). Assurez-vous d’avoir installé la dernière version d’Eclipse. Pour configurer le JDK dans Eclipse, procédez comme suit :
1. Ouvrez Eclipse et créez un projet Java, ou ouvrez-en un existant.
2. Faites un clic droit sur le projet dans Package Explorer, puis sélectionnez Properties.
3. Dans la section Java Build Path, cliquez sur l’onglet Libraries.
4. Cliquez sur Add Library..., sélectionnez JRE System Library, puis cliquez sur Next.
5. Choisissez Workspace default JRE, puis sélectionnez JDK 16 ou une version ultérieure dans la liste déroulante. Cliquez sur Finish.
6. Dans la section Java Compiler, définissez Compiler compliance level sur 16.
7. Cliquez sur Apply and Close pour enregistrer les modifications.
Eclipse est maintenant configuré pour fonctionner avec les records Java.
Visual Studio Code
Visual Studio Code prend en charge les records Java grâce à l’extension [Language Support for Java(TM) by Red Hat](https://marketplace.visualstudio.com/items?itemName=redhat.java). Assurez-vous d’avoir installé la dernière version de Visual Studio Code ainsi que l’extension Java. Pour configurer le JDK dans Visual Studio Code, procédez comme suit :
1. Ouvrez Visual Studio Code et créez un projet Java, ou ouvrez-en un existant.
2. Appuyez sur Ctrl+Shift+P (ou Cmd+Shift+P sous macOS) pour ouvrir la palette de commandes.
3. Saisissez Java: Configure Java Runtime, puis appuyez sur Entrée.
4. Dans la section Java Tooling Runtime, cliquez sur JDK, puis sélectionnez JDK 16 ou une version ultérieure dans la liste déroulante.
5. Redémarrez Visual Studio Code pour appliquer les modifications.
Visual Studio Code est maintenant configuré pour fonctionner avec les records Java.
Votre environnement de développement est prêt. Vous pouvez maintenant utiliser les records Java pour améliorer la lisibilité, l’immutabilité et la sécurité de votre application Java.
Créer un record
Dans cette section, nous présenterons la syntaxe et la structure de base des records Java, puis un exemple de code montrera comment créer une déclaration de record simple. Les records sont une fonctionnalité pratique introduite en préversion dans Java 14, puis finalisée dans Java 16, qui simplifie la création de classes de données. Un record est essentiellement une classe servant à stocker des données immuables, avec un minimum de code répétitif.
Syntaxe et structure de base
La syntaxe de base pour déclarer un record en Java est la suivante :
```java
record RecordName (Type1 field1, Type2 field2, ..., TypeN fieldN) {
// Additional methods and logic can be added here
}
```Une déclaration de record se compose du mot-clé record, suivi du nom du record et d’une liste de champs entre parenthèses. Chaque champ est déclaré avec son type et son nom, séparés par des virgules. Le corps du record, délimité par des accolades, peut contenir des méthodes et une logique supplémentaires, si nécessaire.
Examinons les principales caractéristiques des records :
1. Par défaut, les records sont immuables : une fois une instance créée, les valeurs de ses champs ne peuvent plus être modifiées.
2. Les champs d’un record sont finaux et ne peuvent donc pas être modifiés.
3. Les records génèrent automatiquement des implémentations par défaut pour les méthodes suivantes : equals(), hashCode(), toString(), ainsi que les méthodes d’accès (getters) pour chaque champ.
4. Les records peuvent contenir des méthodes et une logique supplémentaires, mais pas de champs d’instance modifiables.
Exemple de code : déclaration d’un record simple
Dans cet exemple, nous allons créer une déclaration de record simple pour un record Person, qui contient trois champs : firstName, lastName et age.
```java
public record Person(String firstName, String lastName, int age) {
// Additional methods and logic can be added here, if needed
}
```Créons maintenant une instance du record Person et voyons comment fonctionnent les méthodes générées automatiquement :
```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
}
}
```Comme vous pouvez le constater, nous avons pu créer une déclaration de record simple avec un minimum de code répétitif. Les méthodes d’accès générées, ainsi que les méthodes toString() et equals(), fonctionnent comme prévu.
En conclusion, les records Java offrent un moyen concis et pratique de créer des classes de données immuables, avec un minimum de code. En les utilisant, vous pouvez améliorer la lisibilité et la facilité de maintenance de vos applications Java, tout en renforçant leur sécurité grâce à l’immutabilité.
Ajouter des méthodes et de la validation aux records
Introduits dans JDK 16, les records Java offrent une nouvelle façon de créer des classes de données simples et concises, axées sur le stockage de données modifiables. Bien que les records soient principalement conçus pour être immuables et ne contenir que des méthodes d’accès simples, vous pouvez tout de même leur ajouter des méthodes personnalisées et une logique de validation. Dans cette section, nous verrons comment procéder pour améliorer la sécurité et la robustesse de votre application.
Ajouter des méthodes personnalisées aux records
L’un des avantages des records est qu’ils génèrent automatiquement des méthodes d’accès, ainsi que equals(), hashCode() et toString(). Vous pouvez toutefois avoir besoin de méthodes personnalisées pour effectuer des calculs ou des opérations spécifiques sur les données stockées dans le record. Pour cela, il vous suffit de définir la méthode personnalisée dans le corps du record. Notez que ces méthodes ne doivent pas modifier les données du record, afin de préserver son immutabilité.
Voici un exemple d’ajout d’une méthode personnalisée à un record :
```java
record Employee(String name, int age, double salary) {
public double calculateYearlyBonus() {
return salary * 0.1;
}
}
```Dans cet exemple, nous avons ajouté une méthode personnalisée calculateYearlyBonus() au record Employee. Cette méthode calcule la prime annuelle en fonction du salaire de l’employé.
Exemple de code : ajouter une validation à un record
Il est essentiel de valider un record pour garantir que les données qu’il stocke sont valides et sécurisées. La validation peut contribuer à prévenir des vulnérabilités de sécurité, comme la falsification de données ou les attaques par injection. Pour valider un record, vous pouvez utiliser le constructeur compact, qui permet de définir un constructeur de record de façon concise, sans spécifier explicitement les paramètres.
Voici un exemple d’ajout de validation à un record :
```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);
}
}
```Dans cet exemple, nous avons ajouté une validation au record EmailAddress pour vérifier que l’adresse e-mail n’est ni nulle ni vide et qu’elle respecte un format valide. Nous avons utilisé un constructeur compact pour ajouter la logique de validation, ainsi qu’une méthode privée isValidEmail() pour vérifier le format de l’adresse.
Grâce à ces techniques, vous pouvez renforcer la sécurité et la robustesse de vos applications Java en ajoutant des méthodes personnalisées et une logique de validation à vos records. Vous pouvez ainsi garantir la sécurité et la validité des données de votre application, et en améliorer la qualité et la résilience globales.
Utiliser les records avec d’autres fonctionnalités Java
Introduits en préversion dans JDK 14, puis finalisés dans JDK 16, les records Java apportent davantage de simplicité et de concision au langage. Ils sont particulièrement utiles pour modéliser des classes servant à transporter des données, qui nécessitent traditionnellement beaucoup de code répétitif. Dans cette section, nous verrons comment utiliser les records avec d’autres fonctionnalités Java, comme les interfaces et l’héritage, afin d’améliorer la sécurité du code et la facilité de maintenance de votre application Java.
Records et interfaces
Un record ne peut pas étendre une autre classe, mais il peut implémenter une ou plusieurs interfaces. Vous pouvez ainsi utiliser les records avec des modèles de conception éprouvés et tirer parti des avantages des records et des interfaces dans votre application. Examinons un exemple simple.
Supposons que nous ayons une interface appelée Displayable, qui représente les objets pouvant être affichés à l’écran :
```java
public interface Displayable {
String display();
}
```Nous pouvons créer un record qui implémente cette interface :
```java
public record Person(String name, int age) implements Displayable {
@Override
public String display() {
return "Name: " + name + ", Age: " + age;
}
}
```Dans cet exemple, le record Person implémente l’interface Displayable et fournit une implémentation concrète de la méthode display(). Le record Person peut ainsi être utilisé partout où un objet Displayable est attendu.
Records et héritage
Comme indiqué précédemment, les records ne peuvent pas étendre d’autres classes. En effet, ils sont implicitement finaux et héritent de la classe java.lang.Record, ce qui les empêche de participer à l’héritage classique des classes. Toutefois, comme le montre l’exemple précédent, les records peuvent faire partie d’une hiérarchie de types grâce aux interfaces.
Il est important de noter que les records ne doivent pas servir de classe de base à d’autres classes. Leur rôle premier est de transporter des données de façon simple et immuable. Leur ajouter des fonctionnalités par héritage peut entraîner des effets secondaires indésirables et rendre le code plus complexe.
Exemple de code : combiner les records avec d’autres fonctionnalités Java
Maintenant que nous savons comment les records peuvent fonctionner avec les interfaces et l’héritage, examinons un exemple concret. Supposons que nous travaillions sur une application de gestion de projets et que nous souhaitions modéliser différents types de tâches.
Nous pouvons commencer par définir une interface Task :
```java
public interface Task {
String getDescription();
int getPriority();
boolean isCompleted();
}
```Ensuite, nous pouvons créer un record pour chaque type de tâche, en implémentant l’interface Task :
```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
}
}
```Dans cet exemple, nous avons deux records, BugFix et Feature, qui implémentent tous deux l’interface Task. Nous pouvons ainsi traiter les deux types de tâches de manière uniforme dans notre application de gestion de projets, tout en profitant de la simplicité et de l’immutabilité des records.
Priorisez ce qui compte le plus
Les organisations ont besoin d’une approche globale pour hiérarchiser les risques. Avec Snyk, priorisez les risques selon leur contexte.