Java Records 是否可以完全取代 Lombok 库?
共 4928字,需浏览 10分钟
·
2022-06-09 17:22
原文链接 丨https://dzone.com/articles/records-vs-lombok
作者丨Gabriel Solano
译者丨W3CSChool编程狮
在过去很长的一段时间内,Java 总是因为其冗长而遭受到开发者的诟病。即使是对Java有着最大热情的开发者也不得不承认,声明一个只有两个属性的bean类是一件荒谬的事情。
当你按照推荐规范来书写代码,你不仅需要添加 getter 和 setter 方法,而且还要添加 toString、hashcode 以及 equals 方法的重写。结果就是你获得了一大块的代码,然后就开心愉快地去选择另外一门语言。
import java.util.Objects;
public class car{
private String brand;
private String model;
private int year;
public String getBrand(){
return brand;
}
public void setBrand(String brand){
this.brand = brand;
}
public String getModel(){
return model;
}
public void setModel(String model){
this.model = model;
}
public int getYear(){
return year;
}
public void setYear(String year){
this.year = year;
}
@override
public String toString(){
return "Car{" +
"brand='" + brand + '\'' +
", model='" + model + '\'' +
", year=" + year +
'}';
}
@override
public boolean equals(Object o){
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car)o;
return year == car.year && Objects.equals(brand, car.brand) && Object.equals(model, car.model);
}
@override
public int hashCode(){
return Objects.hash(brand, model, year);
}
}
值得庆幸的是,Lombok 库的出现拯救了 Java 开发者,大大地减轻了编码时的痛苦。但是,自从有了和 Lombok 相似功能的 Java Records 类,人们就很想知道现在能否用 Record 取代 Lombok?
它是一个与开发环境高度集成的 Java 库,可以通过注释改进代码。它在 Java 社区中被高度接受和使用。
使用了 Lombok,我们的 Car 类如下:
import lombok.Data;
@Data
public class car{
private String brand;
private String model;
private int year;
}
代码是不是变得更干净,更令人赏心悦目。同时,这样写也不会影响我们之前版本的所有功能。
定义的每一个 Java Record 类型都可以被看作是值对象模式的实现。实质上还是一个 Java 类,其中所有实例都是不可变的。因此,在创建对象时所有类属性都需要传递。Java Record 是在 Java 14 中引入的,几乎可以肯定它将继续发展来改进类的设计。
通过 Record 创建的 Car 类如下:
public record Car(String brand, String model, int year){
}
和前面的版本相比,改进得就更为明显了。
下面将从 Lombok 的一些特性,并通过 Record 进行比较,评估后者能否完全取代前者。
Record 在默认情况下是不可变的,这就意味着所有的类属性都会被隐式声明为 final。我们通常会认为 Record 和值对象很相似,但是它们没有 setter 方法,所有的值都需要在构造函数中传递。而 Lombok 可以通过@Value注释来做同样的事情,但也可以只使用@Data注释来保持可变性。
impoprt lombok.Value;
@Value
public class Car{
private String brand;
private String model;
private int year;
}
Record 并不意味着会遵循 Bean 公约,访问器方法不使用 getX 命名,并且该类不提供 setter 或无参构造函数。另一方面,对于 Lombok , 只需要使用@Data注释即可以将类转换为 Java Bean。
Builder 模式是一种很好的设计模式,可以改进我们的对象创建语法。Lombok 提供了一个方便的注释,它为我们实现了这个模式的所有样板代码。Java Records 目前不打算提供此实现。
import lombok.Builder;
@Builder
public class Cart{
private String brand;
private String model;
private int year;
public static void main(Stringp[] args){
Car myCamaro = Car.builder()
.brand("Chevrolet")
.model("Camaro")
.year(2022)
.build();
}
}
Record 只对少量参数的类是友好的。但是,如果再向其中添加 10 个参数,那么得到的会是一个庞大的构造函数,随之而来的还有多参构造函数所带来的固有的问题。
public record DetailedCar(
String brand, String model, int year,
String engineCode, String engineType, String requireFuel,
String fuelSystem, String maxHorsePower, String maxTorque,
float fuelCapactiy ){
}
DetailedCar camaroDetailed = new DetailedCar(
"Chevrolet", "Camaro", 2022, "LTG", "Turbocharged",
"Gas I4", "Direct Injection", "275 @ 560", "295 @ 3000-4500",
19.0f);
使用了 Lombok,我们就可以决定创建 bean 类是选择使用 setter来设置对象的状态,还是使用builder这种更简洁的方式来构造实例。唯一需要注意的是,因为其默认不会强制设置所有属性,所以可能使实例处于属性不完整状态。当然@Builder 注解支持我们将类中所有属性标记为@nonNull,这样在构建时属性就是必需的。如果必需属性缺失设置则会在运行时抛出一个异常,而不是编译时强制抛出异常。
import lombok.Builder;
import lombok.NonNull;
public class DetailedCar {
private String brand;
private String model;
private int year;
private String engineCode;
private String engineType;
private String requiredFuel;
private String fuelSystem;
private String maxHorsePower;
private String maxTorque;
private float fuelCapacity;
public static void main(String[] args) {
DetailedCar camaroIncomplete = DetailedCar.builder()
.brand("Chevrolet")
.model("Camaro")
.year(2022)
.build();
}
}
输出:
Exception in thread "main" java.lang.NullPointerException: engineCode is marked non-null but is null
目前,Java Record类是不支持继承的,所以不能通过扩展其他Record类来创建一个新的Record类,这可能是模型设计的一个限制。尽管如此,我们也要认识到组合优于继承。
Lombok注释可以参数化来考虑toString /hashCode/equals 方法中的父类属性。
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Car extends MotorVehicle {
private String brand;
private String model;
private int year;
}
Record 是Java 的一个非常棒的新特性,它正推动代码向更简洁的正确方向发展,因此应该多使用 Record。但是,对于提供了众多功能的Lombok,考虑到Java变更的缓慢速度,要在项目中将其彻底取代似乎还为时尚早。
以上就是关于 Record 能否完全取代 Lombok 的详细内容,Record 和 Lombok 你更钟意哪一个?请在评论区留下你的看法。
这里是 W3CSchool 编程狮,点击关注我们,阅读更多IT资讯和技术干货 ~
课程:《Java基础入门到框架时间》
讲师介绍:丁鹏
课程介绍:Java是一门主流的、应用广泛的,功能强大且简单易用的计算机编程语言。在所有的开发岗中,市场对Java的需求最多,同时Java工程师也数量庞大。
课程特点:
1. 不要复制代码,一定得自己敲;
2. 每节课程学完,要善于总结归纳;
3. 复习比学习更重要,务必打好基础;
学习方式:扫码 ↓ 购买立即开始学习~