Lombok,AutoValue和Immutables,或如何编写更少,更好的代码返回

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

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

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

因此,我们已经知道使用Lombok批注的Person类的外观

@Builder(toBuilder = true)
@ToString
@EqualsAndHashCode
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Person {@NonNull@Getterprivate final String lastName;@NonNull@Getterprivate final String firstName;@NonNull@Getterprivate 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, 也不能 。

为什么要使用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();@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.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/347951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

福州PHP讲师招聘_“艺”起就业|招聘信息汇总

亲爱的美术学院毕业生们在全国上下万众一心抗击新冠肺炎疫情的关键时期学院党委高度重视并时刻关注着每一位毕业生的就业工作为进一步做好疫情防控工作也为进一步确保同学们顺利求职就业保障毕业生就业工作的时效性学院公众号特别设立“艺”起就业—招聘信息发布栏目 由院学工…

哪个app最费电_关于石墨烯养生地暖,业主最关心的几大问题,答案附上!

很多人对石墨烯地暖有些许误解,不敢轻易接受。其实不然,石墨烯地暖是一种供热效果好、安全性高、运用寿命长、节能环保的新型健康采暖方式,不仅适用于住宅小区、别墅等家庭采暖,也可用于办公楼、医院等各类公共建筑采暖。在众多对…

cpu 抖动_微抖动,繁忙的等待和绑定CPU

cpu 抖动性能分析新机器 当我在新机器上工作时,我想了解它的局限性。 在这篇文章中,我将研究机器的抖动以及忙于等待本周末构建的新PC的影响。 该机器的规格很有趣,但不是发布目的。 永远不要少于它们: i7-3970X六核运行于4.5 GH…

两端分散对齐怎么设置_Word文字很难对齐?用这4个方法,2秒可对齐所有文字!...

日常工作中,我们在给Word文档进行对齐操作的时候,很多人都是猛敲空格键来对齐文字,通常是一顿操作猛如虎,仔细一看原地杵。简单的文字对齐,这种方法可能还算凑效,但稍显复杂的就不那么管用了。今天叨叨君就…

怎样学c++程序语言,如何学好 C++——学习门槛最高的编程语言

根据InfoQ 编程语言 2 月排行榜,统计发现,学习门槛最高的编程语言是 C。那么如何学好这门又难、门槛又高的语言呢?前面我们介绍过C。C是一种面向对象的计算机程序设计语言,由美国AT&T贝尔实验室的本贾尼斯特劳斯特卢普博士在2…

首个JDK 10(18.3)发行候选版(内部版本43)展示了新的版本控制方案

Mark Reinhold的帖子“ JDK 10:First Release Candidate ”宣布“内部版本43中没有未解决的P1错误”,并将Build 43命名为最初的JDK 10版本候选 。 Reinhold帖子还指向“ JDK 10 Early Access Builds ”页面,该页面包含发行说明的链接。 到基于…

7 centos 查看程序文件数量_CentOS之使用Systemd添加自定义系统服务

文章引言Systemd 就是为了解决Linux 的启动一直采用init进程问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。根据 Linux 惯例,字母d是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是…

做完c语言通讯录系统后的小结,c语言通讯录管理系统的总结

c语言通讯录管理系统的总结c语言通讯录管理系统的总结c语言课设管理系统总结完成情况防暴力输入密码加密输入并删除管理员和用户端两个端管理员对用户的账号删除注册用户用户的账户名及密码修改用户基本操作管理员基本操作存在的问题管理员无法对用户的数据进行修改未使用链表由…

因特尔显卡自定义分辨率_电脑显示器分辨率超频教程:1080P超2K分辨率的方法...

我们玩过CPU超频、显卡超频、内存超频等,相信不少用户还没有尝试过显示器超频,其实在前段时间,装机之家为广大爱好者发布了一篇【电脑显示器刷新率怎么超频?电脑显示器提高屏幕刷新率超频教程】文章,我们将一款普通60H…

Java 9示例–收集的工厂方法–创建不可修改的列表,集合和映射

大家好,这是我在该博客上发表的有关Java 9功能的第一篇文章,今天您将了解我最喜欢的功能“收集的工厂方法” ,它是JEP 269的一部分。JEP代表JDK增强建议。 如果您曾经在Groovy或Kotlin工作过,那么您就会知道使用集合文字使用元素创…

郴州郴锦机器人_减税降费宣传走进郴州市民营企业高质量发展专题培训班

红网时刻郴州8月23日讯(通讯员 陈磊 记者 欧群军)“毫不动摇支持民营经济健康发展离不开税收政策的有力支持。近年来,特别是今年以来国家系列税收优惠政策的出台,为民营经济的发展注入了新的活力。”8月22日,郴州市税务局减税降费宣讲课堂走进…

FPGA(8)--频率计检测控制系统

文章目录一、设计要求1.整体控制系统设计要求2.频率计检测设计要求二、设计思路1.确定VHDL描述与原理图相结合完成设计2.确定状态情况3.数码管显示功能三、设计内容1. 频率检测部分VHDL描述2. 七段数码管显示部分VHDL描述3. 系统主控制部分VHDL描述4.将三个部分的VHDL描述分别都…

lda进行图片分类_LDA主题模型

今天来啃硬骨头了,说说LDA主题模型。本文言简意赅,没有太多的数学公式。学习也不要太多的陷入算法的细枝末节之中,学习复杂的事物,需要从整体去把握。先列出本文的讲解顺序。什么是LDA模型2. 函数与 Beta函数3.共轭先验分布4.二项…

FPGA(1)--VHDL--6选1数据选择器

一、实验目的 掌握用VHDL语句进行组合电路设计的方法,并熟悉程序的编译、调试与波形图的仿真。 二、实验内容 分别用VHDL的CASE语句及IF语句两种方法,设计6选1数据选择器。通过编译、仿真验证功能正确性。 三、实验设计 设计的依据:教材…

android+4.4+jni闪退,native2.1 安卓退到后台时,概率闪退

赞同来自:同样的,在这个时候,还出了另一个错误,详情见下面的log,这个问题,出现的情况就和上面的不同,从5.0 - 9.0 ,level 22- level 28 ,都在出这个错误,真的搞不太清楚是为什么&…

java 模板方法设计模式_Java中的模板方法设计模式

java 模板方法设计模式模板方法是一种行为设计模式 ,用于创建方法存根并将某些实现步骤推迟到子类。 模板方法定义了执行算法的步骤,它可以提供默认实现,该实现对于所有或某些子类可能是通用的。 让我们通过一个例子来理解这种模式&#xff…

FPGA(2)--例化语句--1位全加器

文章目录一、实验目的二、实验内容三、实验设计四、实验结果及仿真一、实验目的 熟悉元件封装方法,掌握层次化电路设计方法;掌握VHDL例化语句的设计方法。 二、实验内容 1.用VHDL语言设计1位全加器,其中仅就半加器实体进行例化声明及端口映…

对mysql的总结与反思_一次DB故障引起的反思和MySQL Operator选型

前言在一次数据库故障后,我们发现业务库会根据业务的等级会划分多个 MySQL 实例,许多业务库会同时属于一个 MySQL 实例,当一个库引发问题后整个实例的状态是不可控的。从而导致这个实例上的所有业务不稳定甚至造成中断。故障反思微服务架构微…

android 三星 拍照,安卓里面拍照最好的三个品牌,OPPO华为三星怎么选

原标题:安卓里面拍照最好的三个品牌,OPPO华为三星怎么选几乎每一个节日都能被国内的商家抓住并且成功的策划为一次次的「购物节」,双十一、双十二等无一例外,3月7日这个从中国高校里衍生出来的「女生」节如今也成为了「女神节」。…

FPGA(3)--VHDL及原理图--4位全加器

文章目录一、实验目的二、实验内容三、实验设计五、实验思考与总结一、实验目的 掌握例化语句的使用方法,掌握使用程序文本和原理图结合方法设计电路,掌握利用包含算术操作符的重载函数的使用。 二、实验内容 首先用VHDL语言设计1位全加器&#xff0c…