Les classes immuables sont bénéfiques car elles sont intrinsèquement thread-safe, faciles à raisonner et empêchent les modifications accidentelles de l'état de l'objet. L'état d'un objet immuable ne peut pas être modifié après sa création, ce qui en fait un modèle de conception précieux, en particulier dans les environnements multithread.
Considérez la classe d'employés suivante :
final class Employee { private final long id; private final String name; private final double salary; public Employee(long id, String name, double salary) { this.id = id; this.name = name; this.salary = salary; } public long getId() { return id; } public String getName() { return name; } public double getSalary() { return salary; } }
Dans cette approche traditionnelle :
Bien que cette approche fonctionne bien, elle implique d'écrire du code passe-partout pour les constructeurs, les getters et parfois les méthodes égales, hashCode et toString.
Lombok peut réduire considérablement la quantité de code que vous devez écrire. Voici comment vous pouvez obtenir la même fonctionnalité avec Lombok :
import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter final class Employee { private final long id; private final String name; private final double salary; }
Cette version utilise les annotations Lombok pour générer automatiquement le constructeur et les getters :
L'annotation @Value de Lombok est une alternative plus puissante qui combine plusieurs fonctionnalités pour créer une classe immuable :
import lombok.Value; @Value class Employee { long id; String name; double salary; }
Avec @Value, Lombok automatiquement :
Cela réduit la définition de votre classe aux seuls champs, avec tout le code nécessaire généré automatiquement.
Les objets immuables ne permettent pas de modifier leur état. Cependant, dans certains cas, vous devrez peut-être créer une copie modifiée de l'objet, comme par exemple mettre à jour le salaire d'un employé. Sans Lombok, cela pourrait ressembler à :
@Value class Employee { long id; String name; double salary; } class Main { public static void main(String... args) { var emp = new Employee(1L, "Aman", 10_000.0); emp = updateSalary(emp, 12_0000.0); } public Employee updateSalary(Employee emp, long newSalary) { return new Employee(emp.getId(), emp.getName(), newSalary); } }
C'est simple mais fastidieux, surtout lorsqu'il s'agit de classes qui comportent de nombreux domaines.
L'annotation @With de Lombok simplifie cela :
import lombok.Value; import lombok.With; @Value class Employee { long id; String name; @With double salary; } class Main { public static void main(String... args) { var emp = new Employee(1L, "Aman", 10_000.0); emp = updateSalary(emp, 12_0000.0); } public Employee updateSalary(Employee emp, double newSalary) { return emp.withSalary(newSalary); } }
L'annotation @With génère une méthode qui renvoie une nouvelle instance de la classe avec le champ spécifié mis à jour, laissant le reste inchangé.
La version dé-lombokée de notre classe Employee (c'est-à-dire ce que Lombok génère sous le capot) ressemblerait à ceci :
final class Employee { private final long id; private final String name; private final double salary; public Employee(long id, String name, double salary) { this.id = id; this.name = name; this.salary = salary; } public Employee withSalary(double salary) { return this.salary == salary ? this : new Employee(this.id, this.name, salary); } public long getId() { return this.id; } public String getName() { return this.name; } public double getSalary() { return this.salary; } @Override public boolean equals(final Object o) { if (o == this) return true; if (!(o instanceof Employee)) return false; final Employee other = (Employee) o; if (this.getId() != other.getId()) return false; final Object this$name = this.getName(); final Object other$name = other.getName(); if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false; return Double.compare(this.getSalary(), other.getSalary()) == 0; } @Override public int hashCode() { final int PRIME = 59; int result = 1; final long $id = this.getId(); result = result * PRIME + (int) ($id >>> 32 ^ $id); final Object $name = this.getName(); result = result * PRIME + ($name == null ? 43 : $name.hashCode()); final long $salary = Double.doubleToLongBits(this.getSalary()); result = result * PRIME + (int) ($salary >>> 32 ^ $salary); return result; } @Override public String toString() { return "Employee(id=" + this.getId() + ", name=" + this.getName() + ", salary=" + this.getSalary() + ")"; } }
Bien que Lombok simplifie la création de classes immuables, il est important de noter certains pièges potentiels :
Bien que l'immuabilité offre des avantages significatifs, il est important de prendre en compte l'impact sur les performances, en particulier dans les scénarios impliquant des mises à jour fréquentes :
Les annotations @Value et @With de Lombok offrent un moyen puissant et concis de créer des classes immuables en Java, éliminant le besoin de code passe-partout et rendant votre code plus lisible et maintenable. En tirant parti de ces annotations, vous pouvez vous concentrer sur la logique de votre application plutôt que sur les mécanismes de conception de classe.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!