Java Records 是否可以完全取代 Lombok 库?

w3cschool

共 4928字,需浏览 10分钟

 ·

2022-06-09 17:22

点击上方蓝字关注我们


  • 原文链接 丨https://dzone.com/articles/records-vs-lombok

  • 作者丨Gabriel Solano

  • 译者丨W3CSChool编程狮



01
PART
前言

在过去很长的一段时间内,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?


02
PART
Lombok 是什么?

它是一个与开发环境高度集成的 Java 库,可以通过注释改进代码。它在 Java 社区中被高度接受和使用。


使用了 Lombok,我们的 Car 类如下:


import lombok.Data;@Datapublic class car{  private String brand;  private String model;  private int year;}


代码是不是变得更干净,更令人赏心悦目。同时,这样写也不会影响我们之前版本的所有功能。


03
PART
Java Record 是什么?


定义的每一个 Java Record 类型都可以被看作是值对象模式的实现。实质上还是一个 Java 类,其中所有实例都是不可变的。因此,在创建对象时所有类属性都需要传递。Java Record 是在 Java 14 中引入的,几乎可以肯定它将继续发展来改进类的设计。


通过 Record 创建的 Car 类如下:


public record Car(String brand, String model, int year){
}


和前面的版本相比,改进得就更为明显了。


下面将从 Lombok 的一些特性,并通过 Record 进行比较,评估后者能否完全取代前者。


04
PART
不可变性

Record 在默认情况下是不可变的,这就意味着所有的类属性都会被隐式声明为 final。我们通常会认为 Record 和值对象很相似,但是它们没有 setter 方法,所有的值都需要在构造函数中传递。而 Lombok 可以通过@Value注释来做同样的事情,但也可以只使用@Data注释来保持可变性。


impoprt lombok.Value;@Valuepublic class Car{  private String brand;  private String model;  private int year;}

05
PART
Bean 公约

Record 并不意味着会遵循 Bean 公约,访问器方法不使用 getX 命名,并且该类不提供 setter 或无参构造函数。另一方面,对于 Lombok , 只需要使用@Data注释即可以将类转换为 Java Bean。


06
PART
Builder

Builder 模式是一种很好的设计模式,可以改进我们的对象创建语法。Lombok 提供了一个方便的注释,它为我们实现了这个模式的所有样板代码。Java Records 目前不打算提供此实现。


import lombok.Builder;@Builderpublic 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();  }}

07
PART
多参数类

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;
@Builderpublic class DetailedCar { @NonNull private String brand; @NonNull private String model; @NonNull private int year; @NonNull private String engineCode; @NonNull private String engineType; @NonNull private String requiredFuel; @NonNull private String fuelSystem; @NonNull private String maxHorsePower; @NonNull private String maxTorque; @NonNull 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

08
PART
继承

目前,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;
}

09
PART
总结

Record 是Java 的一个非常棒的新特性,它正推动代码向更简洁的正确方向发展,因此应该多使用 Record。但是,对于提供了众多功能的Lombok,考虑到Java变更的缓慢速度,要在项目中将其彻底取代似乎还为时尚早。


以上就是关于 Record 能否完全取代 Lombok 的详细内容,Record 和 Lombok 你更钟意哪一个?请在评论区留下你的看法。


这里是 W3CSchool 编程狮,点击关注我们,阅读更多IT资讯和技术干货 ~

课程推荐


课程:《Java基础入门到框架时间》

讲师介绍:丁鹏

课程介绍:Java是一门主流的、应用广泛的,功能强大且简单易用的计算机编程语言。在所有的开发岗中,市场对Java的需求最多,同时Java工程师也数量庞大。

课程特点:

1. 不要复制代码,一定得自己敲;

2. 每节课程学完,要善于总结归纳;

3. 复习比学习更重要,务必打好基础;

学习方式:扫码 ↓ 购买立即开始学习~

点击阅读原文,立即跳转课程界面~
浏览 167
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报