不可變類別是有益的,因為它們本質上是線程安全的,易於推理,並且可以防止物件狀態的意外更改。不可變物件的狀態在創建後無法修改,這使其成為一種有價值的設計模式,尤其是在多執行緒環境中。
考慮以下 Employee 類別:
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; } }
採用這種傳統方法:
雖然這種方法效果很好,但它涉及為建構子、getter 編寫樣板程式碼,有時還需要為 equals、hashCode 和 toString 方法編寫樣板程式碼。
Lombok 可以大幅減少您需要編寫的程式碼量。以下是如何使用 Lombok 實現相同功能的方法:
import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor @Getter final class Employee { private final long id; private final String name; private final double salary; }
此版本使用Lombok註解自動產生建構子和getter:
Lombok 的 @Value 註解是一個更強大的替代方案,它結合了多個功能來創建不可變的類別:
import lombok.Value; @Value class Employee { long id; String name; double salary; }
使用@Value,Lombok會自動:
這將您的類別定義簡化為僅包含字段,並自動產生所有必要的程式碼。
不可變物件不允許修改其狀態。但是,在某些情況下,您可能需要建立物件的修改副本,例如更新員工的薪資。如果沒有 Lombok,這可能看起來像:
@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); } }
這很簡單但很乏味,特別是在處理具有許多欄位的類別時。
Lombok 的 @With 註解簡化了這一點:
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); } }
@With 註解產生一個方法,該方法傳回類別的新實例,並更新指定字段,其餘部分保持不變。
我們的 Employee 類別的 de-lomboked 版本(即 Lombok 在背景產生的內容)將如下所示:
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() + ")"; } }
雖然 Lombok 簡化了不可變類的創建,但請務必注意一些潛在的陷阱:
雖然不變性提供了顯著的好處,但考慮效能影響也很重要,特別是在涉及頻繁更新的場景中:
Lombok 的@Value 和@With 註解提供了一種強大而簡潔的方法來在Java 中創建不可變類,消除了對樣板程式碼的需求,並使您的程式碼更具可讀性和可維護性。透過利用這些註釋,您可以專注於應用程式的邏輯,而不是類別設計的機制。
以上是轉變您的 Java 程式碼:利用 Lombok 在短短幾分鐘內釋放不變性的力量!的詳細內容。更多資訊請關注PHP中文網其他相關文章!