7

使用Java 17中的 record 替代 Lombok 的部分功能

 8 months ago
source link: https://www.51cto.com/article/779185.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用Java 17中的 record 替代 Lombok 的部分功能

作者:互联网架构小马哥 2024-01-11 13:21:53
今天我们就来小小的总结下,我们可以在哪些地方,利用record来替换Lombok。

在DD长期更新的Java新特性专栏中,已经介绍过Java 16中开始支持的新特性:record的使用:2分钟学会Java中record关键字的用法

之前只是做了介绍,但没有结合之前的编码习惯或规范来聊聊未来的应用变化。最近正好因为互相review一些合作伙伴的代码,产生了一些讨论话题,主要正针对于有了record之后,其实之前有些用Lombok的场景,是可以替换掉的。

今天我们就来小小的总结下,我们可以在哪些地方,利用record来替换Lombok。

Lombok的威力

Lombok是我一直都喜欢使用的工具,因为它可以让我们的代码变的更加整洁。比如:当我们要写一个User对象的时候,如果不使用Lombok,往往需要写这么多内容:

public class User {
    private String username;
    private String email;
    private int userId;

    public User(String username, String email, int userId) {
        this.username = username;
        this.email = email;
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (userId != user.userId) return false;
        if (username != null ? !username.equals(user.username) : user.username != null) return false;
        return email != null ? email.equals(user.email) : user.email == null;
    }

    @Override
    public int hashCode() {
        int result = username != null ? username.hashCode() : 0;
        result = 31 * result + (email != null ? email.hashCode() : 0);
        result = 31 * result + userId;
        return result;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", email='" + email + '\'' +
                ", userId=" + userId +
                '}';
    }
}

在有了Lombok之后呢,通过使用@Data注解,可以将以上内容缩减到只需要下面这几行即可:

@Data
public class User {
    private String username;
    private String email;
    private int userId;
}

@Data注解涵盖了@Getter、@Setter、@EqualsAndHashCode 和 @toString,所以一个注解就可以实现成员变量的Getter和Setter,equals和hashcode方法的重写,以及toString的重写。大大降低了代码量,让代码看上去更加整洁。

Lombok的问题

虽然Lombok可以帮助我们少些很多代码,但它依然有一些缺点,比如:

  1. Lombok并非Java官方提供,而是第三方依赖,依靠社区维护。对于较新的Java版本通常都会存在兼容性问题,容易产生一些不可预知的奇怪错误。
  2. IDE的兼容限制,并不是所有的IDE都可以完美兼容Lombok,所以可能也会因此产生一些奇怪的错误。

使用record来替代

在之前的Java 新特性:record一文中,已经提到过record类可以根据类的字段自动生成:构造函数、equals()、hashCode() 和 toString()。这个功能就跟上面我们演示的Lombok中的@Data非常类似。

写法的话也非常简单,只需要这样一行即可搞定:

public record UserRecord(String username, String email, int userId) {}

可以看到该代码的整洁度比Lombok的实现更加干净。同时,最关键的一点,这是Java原生支持的,不需要引入任何第三方依赖!

record类定义完成了,具体使用的话就跟平时使用其他类一样,去创建实例和调用方法即可,比如下面这样:

UserRecord userRecord = new UserRecord("didi", "[email protected]", 35);
System.out.println(userRecord.email());
System.out.println(userRecord.toString());

只是,我们在使用的时候需要了解record自动生成的代码与Lombok的区别,就能马上上手。

比如,从上面的例子中我们可以看到一个区别:获取成员变量email的时候,这里并不想传统getter那样以getEmail()的形式生成。

哪些情况替代不了?

record类已经很强大,但目前并不能完全替代Lombok。主要原因如下:

  1. record中定义的成员变量是final类型的,初始化后就不能修改了
  2. record类不能被继承,所以也无法进一步扩展

因此,在用record替代Lombok的时候,更多用来定义静态变量,而不是可能会变化的实例变量。但是,由于record中也可以定义函数,所以对于一些对成员计算获得的内容,也可以实现和使用。

Lombok和record都可以帮助我们编写更加整洁的代码。前者是第三方库,可能存在一些不可预知的问题和IDE兼容问题,但功能更加全面和强大;后者属于Java原生的能力,功能虽弱一些,但用好它也能帮助我们减少很多代码的编写,且IDE兼容性更好。

责任编辑:张燕妮 来源: 互联网架构小马哥

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK