autovalue_AutoValue:生成的不可变值类

autovalue

Google GitHub托管的项目AutoValue之所以有趣,有多种原因。 该项目不仅使为“ 值对象 ”编写更少的Java代码变得容易,而且还为Java注释处理的实际应用提供了概念上简单的演示。 该自动/值项目是由提供谷歌的员工凯文Bourrillion和埃蒙·麦克马纳斯和许可与Apache的版本2的许可 。

《 AutoValue用户指南》简短明了,其简洁和简洁反映了项目本身。 用户指南提供了使用AutoValue的简单示例,讨论了为什么需要 AutoValue,在“ 我如何……”部分中对常见问题进行了简短回答,并概述了与使用AutoValue有关的一些最佳做法 。

下面的代码清单包含一个我手写的简单类,称为Person 。 编写此类时要牢记AutoValue。

人.java

package dustin.examples.autovalue;import com.google.auto.value.AutoValue;/*** Represents an individual as part of demonstration of* GitHub-hosted project google/auto/value* (see https://github.com/google/auto/tree/master/value).*/
@AutoValue  // concrete extension will be generated by AutoValue
abstract class Person
{/*** Create instance of Person.** @param lastName Last name of person.* @param firstName First name of person.* @param birthYear Birth year of person.* @return Instance of Person.*/static Person create(String lastName, String firstName, long birthYear){return new AutoValue_Person(lastName, firstName, birthYear);}/*** Provide Person's last name.** @return Last name of person.*/abstract String lastName();/*** Provide Person's first name.** @return First name of person.*/abstract String firstName();/*** Provide Person's birth year.** @return Person's birth year.*/abstract long birthYear();
}

当使用AutoValue生成完整的“值类”时,只需为AutoValue提供一个抽象类(故意不支持接口)以生成相应的具体扩展。 该abstract类必须使用@AutoValue批注进行注释,必须提供提供值类实例的static方法,并且必须提供暗示值类的受支持字段的public或包范围的abstract访问器方法。

在上面的代码清单中,静态实例创建方法实例化了AutoValue_Person对象,但是我没有定义这样的AutoValue_Person类。 此类是AutoValue生成的类的名称,该类将在对Person.java进行javac编译时执行AutoValue的注释处理时生成。 由此,我们可以看到AutoValue生成的类的命名约定: AutoValue_放在源类的名称之前,以形成生成的类的名称。

Person.java在编译过程中应用AutoValue注释处理进行编译时,将生成生成的类。 就我而言(使用AutoValue 1.2 / auto-value-1.2.jar ),生成了以下代码:

AutoValue_Person.java:由AutoValue生成

package dustin.examples.autovalue;import javax.annotation.Generated;@Generated("com.google.auto.value.processor.AutoValueProcessor")final class AutoValue_Person extends Person {private final String lastName;private final String firstName;private final long birthYear;AutoValue_Person(String lastName,String firstName,long birthYear) {if (lastName == null) {throw new NullPointerException("Null lastName");}this.lastName = lastName;if (firstName == null) {throw new NullPointerException("Null firstName");}this.firstName = firstName;this.birthYear = birthYear;}@OverrideString lastName() {return lastName;}@OverrideString firstName() {return firstName;}@Overridelong birthYear() {return birthYear;}@Overridepublic String toString() {return "Person{"+ "lastName=" + lastName + ", "+ "firstName=" + firstName + ", "+ "birthYear=" + birthYear+ "}";}@Overridepublic boolean equals(Object o) {if (o == this) {return true;}if (o instanceof Person) {Person that = (Person) o;return (this.lastName.equals(that.lastName()))&& (this.firstName.equals(that.firstName()))&& (this.birthYear == that.birthYear());}return false;}@Overridepublic int hashCode() {int h = 1;h *= 1000003;h ^= this.lastName.hashCode();h *= 1000003;h ^= this.firstName.hashCode();h *= 1000003;h ^= (this.birthYear >>> 32) ^ this.birthYear;return h;}}

通过检查生成的代码可以得出以下几点结论:

  • 生成的类扩展了(实现继承)手写的抽象类,从而允许使用代码使用手写类的API,而不必知道正在使用生成的类。
  • 即使没有在源类中直接定义任何字段,也将生成字段; AutoValue解释了提供的abstract访问器方法中的字段。
  • 生成的类不为字段提供“设置” / mutator方法(get / accessor方法)。 这是AutoValue的故意设计决策 ,因为Value Objects的一个关键概念是它们是不可变的。
  • 考虑到每个字段的类型,将自动为每个字段适当地生成equals(Object) , hashCode()和toString()的实现。
  • 在源类和方法上的Javadoc注释不会在生成的扩展类上重现。

使用诸如AutoValue生成之类的方法的主要优点之一是,开发人员可以专注于特定类应支持的更简单的高级概念,并且代码生成可确保一致,正确地实现较低级的细节。 但是,使用这种方法时要记住一些事情,文档的“ 最佳实践”部分是一个不错的地方,可以很早阅读,以了解AutoValue的假设是否适合您的情况。

  • 当开发人员受过足够的训练以检查和维护abstract “源” Java类而不是生成的类时,AutoValue很有可能会有所帮助。
    • 下次注释处理再次生成该类时,对生成类的更改将被覆盖,否则必须停止该类的生成,以免发生这种情况。
  • 您将需要设置build / IDE,以便将生成的类视为“源代码”,从而可以编译abstract类。
  • 如果将可变字段与AutoValue一起使用时,如果要保持不变性,则必须格外小心(通常选择使用Value Objects时就是这种情况)。
  • 查看“ 最佳做法”和“我如何……”部分,以确保没有任何AutoValue的设计假设使它不利于您的需求。

结论

AutoValue允许开发人员编写更简洁的代码,重点放在高级细节上,并将繁琐的底层(通常是容易出错的)细节的实现委派给AutoValue来自动生成代码。 这类似于IDE的源代码生成可以执行的操作,但是AutoValue优于IDE方法的优点是,AutoValue可以在每次编译代码时重新生成源代码,从而使生成的代码保持最新。 AutoValue的这一优势也是Java自定义注释处理功能的一个很好的例子。

翻译自: https://www.javacodegeeks.com/2016/06/autovalue-generated-immutable-value-classes.html

autovalue

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

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

相关文章

舱机器人尾巴毛茸茸_毛茸茸的(Fluffy)——欧美有史以来最伟大的机器人战争机器人...

我们精选了部分网友观点:是一个潜在的十大机器人如果它被更可靠。Wouldve been a potential top 10 robot had it been more reliable.毁灭性的一次了!Devastating once it got going!打击101和Terrorhurtz遗忘和猫造成了重大损失,猫是更糟糕的状态没有毛茸茸的分解…

HH SaaS电商系统的物流单设计

业务说明 物流信息提交后,系统生成物流单,出库单与物流单是一对多的关系 退货时买家填写物流信息,提交后系统生成物流单和入库单,物流单需要保存入库单的id 物流单实体

pcl_openmap_OpenMap教程5 – 3层GIS应用程序

pcl_openmap1.简介 欢迎使用OpenMap系列教程的第5个教程。 OpenMap是一个免费的开源Java GIS库。 这是以前的教程列表: 在第一个教程中,我们创建了一个基本的OpenMap GIS应用程序,该应用程序在JFrame中显示一个从文件系统加载的具有一个形状…

小米登录协议分析_小米温湿度传感器协议分析

博主喜欢玩智能家居的东西,智能家居确实能给家里带了不少的方便。天气热了,博主想做一个:当屋子有人,并温度高于33度时,开空调。博主已有了一套自家的智能家居系统,有网关、人体红外传感器、红外转发器&…

HH SaaS电商系统的商品系统设计

文章目录商品信息结构商品信息总结构商品信息结构图发布商品商品类型虚拟商品服务商品为什么服务商品要分类前端根据服务商品类型来设计不同的界面和交互订单状态和服务类型有关商品档案上下架运营商品上下架(即商品营销上下架)删除商品租户删除自供商品…

jdk170不支持注释_JDK 9 @不建议使用的注释增强功能

jdk170不支持注释在帖子中, Deprecated可能会是什么样子? ,我当时使用JEP 277 (“增强的弃用”)的描述来指导创建增强的自定义Deprecated注释。 但是,自从发布该文章以来,JEP 277进行了重大更改…

对mysql的总结与反思_深入了解MySQL,一篇简短的总结

MySQL的基本语法这里作为MySQL部分模块的深入了解,大部分都是理论方面的笔记,不会写具体用法。具体用法会记录在下面这个随笔分类下,不过暂时还没更新完,等过段时间会更新下事务、存储过程、索引等用法,虽然都很简单&a…

HH SaaS电商系统移动端商城,买家选择商品规格的交互设计

文章目录未完整选择商品规格时商品图如何显示库存如何显示价格如何显示选择规格提示文案如何显示原型图已选完整选择商品规格时商品图如何显示库存如何显示价格如何显示原型图SKU下架后如何显示原型图购买数量如何交互未完整选择商品规格时 商品图如何显示 显示SPU的主图&…

aws lambda_适用于无服务器Java开发人员的AWS Lambda:它为您提供了什么?

aws lambda无服务器计算如何帮助您的生产基础架构? 在过去的几年中,无服务器计算架构一直受到关注,因为它专注于应用程序的主要组件之一:服务器。 这种体系结构采用了不同的方法。 在下面的文章中,我们将解释无服务器…

HH SaaS电商系统的销售订单毛利润模块设计

HH SaaS电商系统的销售订单利润分析,仅是简单分析供运营人员参考而已,所以订单生成后就自动根据商品成本价和实际交易价生成利润表,而不需要等到订单归档后才生成。 销售子单的毛利润最终交易总额-成本总额销售子单的毛利率毛利润/最终交易总…

aes子密钥生成c语言_一种基于流密码算法的子密钥生成方法与流程

本发明涉及一种用于分组加解密算法的子密钥的生成方法。背景技术:随着信息技术的发展,信息安全性的问题却愈来愈显得突出,保证信息安全的一个重要技术就是密码学。密码学在信息安全技术中扮演着基础的角色,是攻击者最难攻破的模块…

学习java很痛苦_Java日期细微的痛苦提醒

学习java很痛苦这些天我不再需要使用java.util.Date了,但是最近选择这样做,这让我想起了使用与Java Date关联的API的痛苦 。 在这篇文章中,我看了弃用的参数化Date构造函数的一些令人惊讶的API期望,该构造函数接受六个整数 。 在…

如何理解程序保存数据就是输出,读取数据就是输入的含义(程序中输入input/输出output的含义如何理解)

文章目录程序是如何保存数据的为什么保存数据的类名称都表达一种输出意思,例如:output程序如何读取数据为什么读取数据的类名称都表达一种输入意思,例如:input总结程序是如何保存数据的 对象的序列化就是持久化,就是把…

hazelcast_HazelCast的Spring-Boot和Cache抽象

hazelcast以前,我们是使用spring提供的默认Cache Manager来开始Spring Cache抽象的。 尽管这种方法可能适合我们对简单应用程序的需求,但是在出现复杂问题的情况下,我们需要使用具有更多功能的其他工具。 Hazelcast就是其中之一。 当涉及到基…

eclipse preference没有server_Java Web开发的前期准备工作,部署Tomcat服务器和Server环境创建...

Java Web: 顾名思义,就是用Java的方式来解决Web开发,我也不讲太多的理论问题,直接将如何上手来进行Java Web开发。那么,我们一般进行Java Web开发,可以使用的工具很多,我这里使用eclipse。选择eclipse的版本…

类似TH养车的电商系统设计思路

平台运营模式B2CO2O,汽车用品全部平台自营,允许线下汽车服务门店入驻,门店运营模式O2O汽车服务全部标准化,由平台创建和维护服务商品根据商品实际使用需要关联服务商品线下汽车服务门店根据自己实际运营的情况选择有能力提供的汽车…

java int不将0忽略_Java微服务:蛋糕是骗人的,但您不能忽略它

java int不将0忽略构建微服务实际上意味着什么? 通过微服务框架的眼光回答 忽略微服务的趋势已变得不可能。 有些人会说这只是另一个难以忍受的流行语,而另一些人会背诵打破巨石的优势或采取逆势方法并关注负面因素。 在本文中,我们将全面了…

4怎么放大字体_Word字体怎么放大?简单教你几招轻松搞定

一般情况下我们都会选择用Word编辑文章。文章编辑完成之后我们通常会对文章进行排版。在排版的过程中如果我们需要将Word字体放大该怎么办呢?下面我就来教大家几个Word字体放大的小技巧,一起来看看吧。下面以放大“字体演示”为例为大家演示操作过程。一…

js splice坑_JavaScript的splice()方法在for循环中使用可能会遇到的坑!!!

在我们日常敲代码的时候,常常会用到splice()方法来删除数组中的元素(就是以截取的方式),因为它会直接对数组进行修改。在使用splice之前,必备条件是,要先有一个数组。var arr new Array(1,2,3,4,5); // 初始化一个数组var delete…

java crud_Java 8流中的数据库CRUD操作

java crud在开始使用新工具时要克服的最大障碍是让您着手处理小事情。 到目前为止,您可能对新的Java 8 Stream API的工作方式充满信心,但是您可能尚未将其用于数据库查询。 为了帮助您开始使用Stream API创建,修改和读取SQL数据库&#xff0c…