不可变类是有益的,因为它们本质上是线程安全的,易于推理,并且可以防止对象状态的意外更改。不可变对象的状态在创建后无法修改,这使其成为一种有价值的设计模式,尤其是在多线程环境中。
考虑以下 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中文网其他相关文章!