lombok插件安装_Lombok,AutoValue和Immutables,或如何编写更少,更好的代码返回

lombok插件安装

lombok插件安装

一篇有关Lombok库的文章中,我描述了一个库,该库有助于处理Java中的样板代码( 是的,我知道这些问题已经在Kotlin中解决了,但这是现实生活,我们不能一味地坐下来,一旦出现较新或更简单的语言,请重写每个现有项目)。 但是生活中有许多事情,Lombok项目有其替代方案。 让我们也给他们一个机会。

本文的代码示例可在此处此处找到。

它实际上是Lombok的替代方案-因为您不能一次使用两者。 或者,至少事实证明,在同一个项目中同时使用IntelliJ IDEAIntelliJ IDEA时,您会遇到很多困难,因为这是许多人真正选择的IDE,因为这两个库处理批注处理的方式不同。 因此,两个人都无法生存,而另一个人则得以幸存,这大约是哈利·波特和伏地魔的预言听起来的样子

因此,我们已经知道Person类带有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;
}

如果我们创建一个新项目并按此处所述使用autovalue ,则可以使用AutoValue Builders模仿几乎相同的模型

现在让我们看看AutoValue模型的外观:

package autovalue.model;

import com.google.auto.value.AutoValue;

@AutoValue
public abstract class Person {
    public abstract String lastName();

    public abstract String firstName();

    public abstract Integer age();

    public static Person create(String lastName, String firstName, Integer age) {
        return builder().lastName(lastName).firstName(firstName).age(age).build();
    }

    public static Builder builder() {
        return new AutoValue_Person.Builder();
    }

    @AutoValue.Builder
    public abstract static class Builder {
        public abstract Builder lastName(String lastName);
        public abstract Builder firstName(String firstName);
        public abstract Builder age(Integer age);

        public abstract Person build();
    }
}

您可以看到的是,肯定有更多的代码

Lombok生成带有单个注释的构建器时, AutoValue将使您创建自己的构建器代码-尽管不是全部。 基本上,您定义接口后,实现将由AutoValue生成的代码完成,您不必实际实现getter和setter中的代码。 即使我们同意AutoValue getter接口不会比Lombok字段定义花费更多的时间或空间,但是对于某些人来说,编写AutoValue构建器代码仍然是一件麻烦事。

但是,它可以提供更大的灵活性,因为您实际上可以更改构建器方法名称。 此外,代码分析和使用情况搜索是一个巨大的胜利–这样,您实际上可以分别查找实际的getter和setter的用法,这对开发人员也可能很重要。

实例的创建方法与Lombok相同。

final Person anna = Person.builder()
        .age(31)
        .firstName("Anna")
        .lastName("Smith")
        .build();

我们所有的测试都在代码更改最少的情况下运行,主要是因为AutoValue无法将实例转换为构建器(或者至少我无法轻易找到它),因此复制只是调用静态工厂方法:

package autovalue.model;

import org.junit.Test;

import static org.assertj.core.api.Java6Assertions.assertThat;

public class PersonTest {
    private static Person JOHN = Person.builder()
            .firstName("John")
            .lastName("Doe")
            .age(30)
            .build();
    private static Person JANE = Person.builder()
            .firstName("Jane")
            .lastName("Doe")
            .age(30)
            .build();

    @Test
    public void testEquals() throws Exception {
        Person JOHN_COPY = Person.create(JOHN.lastName(), JOHN.firstName(), JOHN.age());
        assertThat(JOHN_COPY).isEqualTo(JOHN);
    }

    @Test
    public void testNotEquals() throws Exception {
        assertThat(JANE).isNotEqualTo(JOHN);
    }

    @Test
    public void testHashCode() throws Exception {
        Person JOHN_COPY = Person.create(JOHN.lastName(), JOHN.firstName(), JOHN.age());
        assertThat(JOHN_COPY.hashCode()).isEqualTo(JOHN.hashCode());
    }

    @Test
    public void testHashCodeNotEquals() throws Exception {
        Person JOHN_COPY = Person.create(JOHN.lastName(), JOHN.firstName(), JOHN.age());
        assertThat(JOHN_COPY.hashCode()).isNotEqualTo(JANE.hashCode());
    }

    @Test
    public void testToString() throws Exception {
        String jane = JANE.toString();

        assertThat(jane).contains(JANE.lastName());
        assertThat(jane).contains(JANE.firstName());
        assertThat(jane).contains("" + JANE.age());
        assertThat(jane).doesNotContain(JOHN.firstName());
    }

}

其他显而易见的区别:

为什么要使用AutoValueAutoValue的创建者会谨慎地在此处描述该库的收益,甚至就此创建一个完整的演示文稿

该库还使用Java注释处理器来生成简单,安全和一致的值对象。 好吧,与前两个相同。 还有什么是新的? 让我们来看看。

最简单的值类如下所示。

package immutables.model;

import org.immutables.value.Value;

@Value.Immutable
public abstract class Person {
    public abstract String lastName();
    public abstract String firstName();
    public abstract Integer age();
}

因此,具有抽象类的相同原理仅在生成的代码中实现。 为此,您需要启用IDE注释处理器,就像对Lombok一样(但对于AutoValue则不需要,因为它是由gradle插件完成的)。

那么,对象创建的外观如何?

final Person anna = ImmutablePerson.builder()
        .age(31)
        .firstName("Anna")
        .lastName("Smith")
        .build();
System.out.println(anna);

乍一看,最明显的区别是:

  • 我们不声明构建器方法。
  • 静态builder / factory方法不是在我们自己的类上创建的,而是在生成的类上创建的。
  • 与AutoValue一样,无法在类上生成生成器,只能在生成器上生成。
  • 生成的类也自动-ers,就是实例方法,允许通过改变一个属性来创建实例的副本补充说:
final ImmutablePerson anna = ImmutablePerson.builder()
        .age(31)
        .firstName("Anna")
        .lastName("Smith")
        .build();
System.out.println(anna);

final ImmutablePerson annaTheSecond = anna.withAge(23).withLastName("Smurf");
System.out.println(annaTheSecond);
  • 该构建器具有自动添加的from()方法,该方法允许创建实例的精确副本,并且在生成的类上还有一个生成的静态copyOf()方法:
Person JOHN_COPY = ImmutablePerson.builder().from(JOHN).build();
// OR
Person JOHN_COPY = ImmutablePerson.copyOf(JOHN);

同样,我们的测试运行时所做的更改很小,主要是关于如何复制实例的:

package immutables.model;

import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;


public class PersonTest {
    private static Person JOHN = ImmutablePerson.builder()
            .firstName("John")
            .lastName("Doe")
            .age(30)
            .build();
    private static Person JANE = ImmutablePerson.builder()
            .firstName("Jane")
            .lastName("Doe")
            .age(30)
            .build();

    @Test
    public void testEquals() throws Exception {
        //ImmutablePerson JOHN_COPY = ImmutablePerson.builder().from(JOHN).build();
        Person JOHN_COPY = ImmutablePerson.copyOf(JOHN);
        assertThat(JOHN_COPY).isEqualTo(JOHN);
    }

    @Test
    public void testNotEquals() throws Exception {
        assertThat(JANE).isNotEqualTo(JOHN);
    }

    @Test
    public void testHashCode() throws Exception {
        Person JOHN_COPY = ImmutablePerson.copyOf(JOHN);
        assertThat(JOHN_COPY.hashCode()).isEqualTo(JOHN.hashCode());
    }

    @Test
    public void testHashCodeNotEquals() throws Exception {
        Person JOHN_COPY = ImmutablePerson.copyOf(JOHN);
        assertThat(JOHN_COPY.hashCode()).isNotEqualTo(JANE.hashCode());
    }

    @Test
    public void testToString() throws Exception {
        String jane = JANE.toString();

        assertThat(jane).contains(JANE.firstName());
        assertThat(jane).contains(JANE.lastName());
        assertThat(jane).contains("" + JANE.age());
        assertThat(jane).doesNotContain(JOHN.firstName());
    }

}

关于Immutables库,还有很多要说的,因此这里有一个相当大的手册。 在本文中,我们仅对表面进行了一些刮擦。 例如,有关使用Immitables样式自定义(方法前缀,构建器名称等)以及甚至为Mongo生成存储库以便将文档视为不可变对象的JSON序列化的更多详细信息。 但是,这比我在这篇简单文章中所涉及的要多得多。

要解决的问题是,尚未普及的Java语言的挑战之一就是冗长和样板代码。 但是有许多工具可以处理它,并且可以选择最合适的库,而不是通过复制粘贴或尝试编写自己的代码生成器进行编码。

好好利用它们。

好好用

翻译自: https://www.javacodegeeks.com/2018/03/lombok-autovalue-and-immutables-or-how-to-write-less-and-better-code-returns.html

lombok插件安装

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值