佛山网站建设培训,高能建站,知名网站建设商家,网页搜索青少年普法网官网lombok和maven在上一篇有关Lombok库的文章中 #xff0c;我描述了一个库#xff0c;该库有助于处理Java中的样板代码#xff08; 是的#xff0c;我知道这些问题已经在Kotlin中解决了 #xff0c;但这是现实生活#xff0c;我们不能一味地坐下来#xff0c;一旦出现较新… lombok和maven 在上一篇有关Lombok库的文章中 我描述了一个库该库有助于处理Java中的样板代码 是的我知道这些问题已经在Kotlin中解决了 但这是现实生活我们不能一味地坐下来一旦出现较新或更简单的语言请重写每个现有项目。 但是生活中有很多事情 Lombok项目有其替代方案。 让我们也给他们一个机会。 本文的代码示例可在此处和此处找到。 它实际上是Lombok的替代方案-因为您不能一次使用两者。 或者至少事实证明在同一个项目中同时使用IntelliJ IDEA和IntelliJ IDEA时您将遇到很多困难因为这是许多人真正选择的IDE因为这两个库处理批注处理的方式不同。 因此两个人都无法生存而另一个人则得以幸存这大约是哈利·波特和伏地魔的预言所表达的方式 。 因此我们已经知道使用Lombok批注的Person类的外观 Builder(toBuilder true)
ToString
EqualsAndHashCode
AllArgsConstructor(access AccessLevel.PRIVATE)
public class Person {NonNullGetterprivate final String lastName;NonNullGetterprivate final String firstName;NonNullGetterprivate 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.Builderpublic 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();Testpublic void testEquals() throws Exception {Person JOHN_COPY Person.create(JOHN.lastName(), JOHN.firstName(), JOHN.age());assertThat(JOHN_COPY).isEqualTo(JOHN);}Testpublic void testNotEquals() throws Exception {assertThat(JANE).isNotEqualTo(JOHN);}Testpublic void testHashCode() throws Exception {Person JOHN_COPY Person.create(JOHN.lastName(), JOHN.firstName(), JOHN.age());assertThat(JOHN_COPY.hashCode()).isEqualTo(JOHN.hashCode());}Testpublic void testHashCodeNotEquals() throws Exception {Person JOHN_COPY Person.create(JOHN.lastName(), JOHN.firstName(), JOHN.age());assertThat(JOHN_COPY.hashCode()).isNotEqualTo(JANE.hashCode());}Testpublic 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());}} 其他显而易见的区别 您编写的AutoValue类始终是抽象的。 它们在AutoValue生成的代码中实现。 AutoValue类是自动不可变的。 有一种解决方法使它们具有不可变类型的属性 。 即使您明确希望在实例上具有setter 也不能 。 为什么要使用AutoValue AutoValue的创建者会谨慎地在此处描述该库的收益甚至就此创建一个完整的演示文稿 。 该库还使用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();Testpublic void testEquals() throws Exception {//ImmutablePerson JOHN_COPY ImmutablePerson.builder().from(JOHN).build();Person JOHN_COPY ImmutablePerson.copyOf(JOHN);assertThat(JOHN_COPY).isEqualTo(JOHN);}Testpublic void testNotEquals() throws Exception {assertThat(JANE).isNotEqualTo(JOHN);}Testpublic void testHashCode() throws Exception {Person JOHN_COPY ImmutablePerson.copyOf(JOHN);assertThat(JOHN_COPY.hashCode()).isEqualTo(JOHN.hashCode());}Testpublic void testHashCodeNotEquals() throws Exception {Person JOHN_COPY ImmutablePerson.copyOf(JOHN);assertThat(JOHN_COPY.hashCode()).isNotEqualTo(JANE.hashCode());}Testpublic 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.htmllombok和maven