10

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

 8 months ago
source link: https://www.didispace.com/article/java-17-records-avoid-lombok.html#%E6%80%BB%E7%BB%93
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

在DD长期更新的Java新特性专栏open in new window中,已经介绍过Java 16中开始支持的新特性:recordopen in new window的使用。

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

今天我们就来小小的总结下,我们可以在哪些地方,利用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 新特性:recordopen in new window一文中,已经提到过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中也可以定义函数,所以对于一些对成员计算获得的内容,也可以实现和使用。

# 总结

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

好了,今天的分享就到这里。如果您学习过程中如遇困难?可以加入我们超高质量的技术交流群open in new window,参与交流与讨论,更好的学习与进步!更多Java新特性教程可以点击直达!open in new window,欢迎收藏与转发支持!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK