如何编写更少更好的代码参考Project Lombok

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(155)   2024-06-09 06:20:09

我一直打算写关于 Project Lombok 的文章,以至于当每个有自尊心的 Java 开发人员都已经听说过它时,我可能正在写这篇文章。尽管如此,值得一提的是,如果只是提醒自己应该毫不犹豫地尝试性能增强工具并看看它们是否合适,Lombok 肯定会通过允许以下方式增强 Java 编码器的性能同时编写更少的代码并提高其质量,这不是一件小事。

Java 的反对者通常会说它的弱点是什么?

Java 太冗长了。 (c) 每个 Java 对手

不幸的是,这句话有很多道理。想象一个简单的数据类,你想要存储个人信息——姓名、年龄等。它可能看起来像这样。

  
 public class PersonSimple {
    private String lastName;
    private String firstName;
    private Integer age;

    public String getLastName() {
        return lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public Integer getAge() {
        return age;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

好吧,你说。我用 IDE 生成了所有这些东西,并不难。但我们还需要一个 hashCode()equals()。因为您可能希望将实例保留在集合中并检查是否相等。没问题,大多数 IDE 都允许您生成这些以及 getter 和 setter。他们会加入一个 toString() 生成器来帮助您输出对象并查看其中的内容。

  
 public class PersonSimple {
    private String lastName;
    private String firstName;
    private Integer age;

    public String getLastName() {
        return lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public Integer getAge() {
        return age;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PersonSimple that = (PersonSimple) o;
        return Objects.equals(lastName, that.lastName) &&
                Objects.equals(firstName, that.firstName) &&
                Objects.equals(age, that.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(lastName, firstName, age);
    }

    @Override
    public String toString() {
        return "PersonSimple{" +
                "lastName='" + lastName + '\'' +
                ", firstName='" + firstName + '\'' +
                ", age=" + age +
                '}';
    }
}

那好吧。所有这些东西都是由 IntelliJ IDEA 生成的。没那么难吧?好吧,不。但是现在您正在考虑 Josh Bloch 并决定应用 Builder 模式。这一次,你必须做一些手工工作。你最终可能拥有的将是接近于此的东西。

  
public class PersonSimple {
    private final String lastName;
    private final String firstName;
    private final Integer age;

    private PersonSimple(String lastName, String firstName, Integer age) {
        this.lastName = lastName;
        this.firstName = firstName;
        this.age = age;
    }

    public String getLastName() {
        return lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public Integer getAge() {
        return age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PersonSimple that = (PersonSimple) o;
        return Objects.equals(lastName, that.lastName) &&
                Objects.equals(firstName, that.firstName) &&
                Objects.equals(age, that.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(lastName, firstName, age);
    }

    @Override
    public String toString() {
        return "PersonSimple{" +
                "lastName='" + lastName + '\'' +
                ", firstName='" + firstName + '\'' +
                ", age=" + age +
                '}';
    }
    
    public static class Builder {
        private String lastName;
        private String firstName;
        private Integer age;

        public Builder setLastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder setAge(Integer age) {
            this.age = age;
            return this;
        }
        
        public PersonSimple build() {
            return new PersonSimple(lastName, firstName, age);
        }
     }
}

所以。我们有一个构建器,现在我们的 PersonSimple 可以用这样的一段代码创建。

  
 final PersonSimple john = new Person.Builder()
                .setFirstName("John")
                .setLastName("Doe")
                .setAge(30)
                .build();
        System.out.println(john);

但是你必须创造很多东西。你有:

  • 具有全参数私有构造函数的数据类;
  • 数据类上的三个 getter;
  • 一个带三名二传手的随行建造师班;
  • 调用私有数据类构造函数的构建器类上的build()方法;
  • 尽管已生成,但不要忘记 hashCode()、equals() 和 toString() 方法。

该代码现在需要 70 多行。每次您需要一个新字段时,您都必须至少在三个地方处理它——数据类中的 getter、构建器类中的 setter 和构造函数。

如果我向您展示如何使用 Project Lombok 做同样的事情会怎么样?

好的,开始吧。

  
 @Builder(toBuilder = true)
@ToString
@EqualsAndHashCode
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Person {
    @NonNull
    @Getter
    private final String lastName;
    @NonNull
    @Getter
    private final String firstName;
    @NonNull
    @Getter
    private final Integer age;
}
  • 我们使用@Builder 注释生成了构建器类。 toBuilder=true 意味着我们另外创建了一个 toBuilder() 实例方法,它创建了构建器类的一个新实例,并使用当前实例的值进行了初始化。
  • 我们添加了一个带有 @ToString 注释的 toString() 方法。
  • 我们添加了 hashCode()equals(),您猜对了,@EqualsAndHashCode
  • 我们使用 @AllArgsConstructor(access = AccessLevel.PRIVATE) 将全参数构造函数设为私有。
  • 我们使用 @Getter 注释向类字段添加了标准 getter。

现在是十五行代码。十五!我们刚刚将代码减少了五次。对于有很多领域的班级来说,增益会更好。

那么,Project Lombok 到底做了什么?它会在编译期间生成所有样板文件,让您避免手动编写代码或使用 IDE 生成代码。它为您节省了大量时间,并允许您以更少的努力创建更漂亮的代码。

在你的代码 lombokization 之后,这个人可以像这样创建。

  
  private static Person JOHN = Person.builder()
            .firstName("John")
            .lastName("Doe")
            .age(30)
            .build();

要将 Lombok 添加到您的项目中,您需要为它添加一个依赖项,并且在我的例子中为 IDEA 安装一个 Lombok 插件此处 和 Maven 此处 描述了 Gradle 配置。

这里描述了 Lombok 的所有特性。请看一下,看看是否还有其他有用的东西,因为我在这里描述的只是它所拥有的一小部分。

示例中的代码存储在我的 github 存储库中

祝你代码干净简洁!

标签2: Java教程
地址:https://www.cundage.com/article/jcg-write-less-better-code-project-lombok.html

相关阅读

Java HashSet 教程展示了如何使用 Java HashSet 集合。 Java哈希集 HashSet 是一个不包含重复元素的集合。此类为基本操作(添加、删除、包含和大小)提供恒定时间性...
SpringApplicationBuilder 教程展示了如何使用 SpringApplicationBuilder 创建一个简单的 Spring Boot 应用程序。 春天 是用于创建企业应...
通道是继 buffers 之后 java.nio 的第二个主要新增内容,我们在之前的教程中已经详细了解了这一点。通道提供与 I/O 服务的直接连接。 通道是一种在字节缓冲区和通道另一端的实体(通...
课程大纲 Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了一个分布式的、支持多租户的全文搜索引擎,带有 HTTP Web 界面和无模式的 JSON 文档。 Elasti...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Java 是用于开发各种桌面应用程序、Web 应用程序和移动应用程序的最流行的编程语言之一。以下文章将帮助您快速熟悉 Java 语言,并迈向 API 和云开发等更复杂的概念。 1. Java语言...
Java中的继承是指子类继承或获取父类的所有非私有属性和行为的能力。继承是面向对象编程的四大支柱之一,用于提高层次结构中类之间的代码可重用性。 在本教程中,我们将了解 Java 支持的继承类型,...
Java Message Service 是一种支持正式通信的 API,称为 网络上计算机之间的消息传递。 JMS 为支持 Java 程序的标准消息协议和消息服务提供了一个通用接口。 JMS 提...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...