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

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

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

相关文章

exit(0)与exit(1)、return区别

exit(0):正常运行程序并退出程序; exit(1):非正常运行导致退出程序; return():返回函数,若在主函数中,则会退出函数并返回…

上海教师计算机等级要求,计算机考试阅卷教师谈等级考试

等级考试笔试是由选择题和填空题两大部分组成。选择题是由阅卷系统改卷,而填空题是由阅卷教师评阅,下面我们就从分析阅卷的得分丢分情况来谈谈如何让阅卷教师在公平、公正的前提下尽可能的给予"高分",让考生尽量避免不必要的"…

C++读取文本文件中以TAB作为分隔符,且中间字段有为空的情况的方法?

数据文件:testData.txt 内容: 111 222 444 555思路: getline()将testData.txt中的第一行记录读入到一个string中,然后搜索第n个分隔符进行定位,判断第n个字段长度,使用substr&#x…

宿迁学计算机的学校,宿迁计算机学校

01、宿迁计算机学校培养目标培养学生具有基本的审美能力,利用常用的平面设计软件进行多媒体产品开发、广告设计与创意、印刷品的设计、展览展示等能力,能够从事多媒体产品开发,广告设计与创意,印刷品的设计,展览展示等…

javaone_JavaOne 2012:调查JVM水晶球

javaone我周一回到了希尔顿的A / B广场参加第四届会议,但首先去了希尔顿的顶层收拾午餐。 我每年都在JavaOne的第一天被提醒,对于参与的每个人来说,第一天的午餐获取过程令人惊讶地令人沮丧。 我知道我在JavaOne的第一年的经历使我有些困惑&a…

VS2008编译boost库

一、下载 首先从boost官方主页http://www.boost.org/下载最新版boost安装包,我用的版本是boost.1.49.0 二、新建文件夹 如果是使用下载的安装包,那么请将boost安装包解压至本地新建的目录,如:F:\boost 三、编译 (1&am…

rtk采点后如何导入cad_【干货】RTK实操视频:工程之星5.0操作攻略!(第五部分)...

前期回顾:【干货】RTK实操视频:工程之星5.0操作攻略!(第一部分)【干货】RTK实操视频:工程之星5.0操作教程(第二部分)【干货】RTK实操视频:工程之星5.0操作攻略!(第三部分)【干货】RTK实操视频:工…

Git----分支管理之分支管理策略04

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。 如果要强制禁用Fast forward模式,Git就会在merge时生产一个新的commit,这样&#xf…

测试英语语法的软件,1Checker,一款实用的英语语法检测软件

语法检测软件众多,使用最顺手的是1Checker。因为工作原因,每两年都要发表至少一篇英文期刊,可我的英文水平写专业论文很欠缺,又不愿意花钱找人翻译检测。就在网上寻找相关的软件,1Checker不是我第一个使用的语法检测软…

企业是否应该实现对客户需求的快速响应_如何做好企业服务?

2018 年,企业级服务仍处于高速增长时期。经过几年的市场洗礼后,企业级服务的市场格局正在逐步明朗。无论是垂直型还是通用型的企业级服务厂商,公司发展核心问题主要围绕客户满意度、产品成熟度、企业健康度三方面:①产品成熟度。成熟的 B 端产…

JavaScript的匿名函数

匿名函数&#xff0c;没有函数名的函数&#xff0c;这种函数一般使用变量来存放。匿名函数的声明方式类似普通函数&#xff0c;一般使用变量保存起来。 示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"…

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

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

Linux Shell——-if -eq,if -ne,if -gt[笔记]

-eq //等于 -ne //不等于 -gt //大于 -lt //小于 ge //大于等于 le //小于等于

中国计算机手机全部被黑,云南一高校电脑全被黑

0云南一高校电脑全被黑2016-10-14 21:20据云南高校新鲜事儿10月14日消息&#xff0c;网友爆料&#xff0c;云南大学本部文渊楼授课电脑全部被黑。{"info": {"setname": "云南一高校电脑全被黑","imgsum_bk": 4,"imgsum": 4,…

CIFAR和SVHN在各CNN论文中的结果

CIFAR和SVHN结果 加粗表示原论文中该网络的最优结果。可以看出DenseNet-BC优于ResNeXt优于DenseNet优于WRN优于FractalNet优于ResNetv2优于ResNet。ResNeXt-29&#xff0c;8x64d表示29层&#xff0c;ResNeXt分支数为8&#xff0c;每个分支的bottleneck宽度为64。这里记录的结果…

c++可以做什么项目_上班做下班后可以做的兼职项目

当今社会我们常常听到有人抱怨成年人的世界里从来没有容易二字&#xff0c;无论你是在家带娃&#xff0c;还是正常上班。你会觉得消费水平在不断的上涨&#xff0c;但工资却永不见涨。眼看着入不敷出&#xff0c;除了心里急的火急火燎&#xff0c;心里还想着怎样赚到更多的钱&a…

excel中自动填充到最后一行

excel中如果中间没有空行&#xff0c;通过双击黑色十字可自动填充到最后一行&#xff0c;但如果数据中间空行多并且数据多&#xff0c;双击黑色十字只可以填充到空行前面的一行。 这时&#xff0c;可使用ctrlenter组合键实现自动填充。 1、先选中要填充的单元格 2、输入公式 3、…

强制关闭计算机窗口,windows系统怎么取消关机时强制关闭程序提示窗口?

在写经验时&#xff0c;因为要操作用户帐户&#xff0c;结果弄得系统所有设置都恢复到系统默认状态了&#xff0c;其它的就不说&#xff0c;说一下关机时&#xff0c;总会弹出一个“强制关闭程序的提示窗口”&#xff0c;怎样把这个窗口关闭掉呢。找了一些资料&#xff0c;终于…

更改exe程序图标_更改电脑文件夹颜色、样式、图标,让文件夹不再是单一的黄色...

电脑文件夹一般默认的是样式、图标、颜色&#xff0c;如下图所示&#xff1a;文件夹那么&#xff0c;怎样改变这三种设定呢&#xff1f;其实操作很简单&#xff0c;下面小编介绍一个小工具&#xff0c;具体的操作步骤如下&#xff1a;1、首先&#xff0c;下载安装&#xff0c;下…

Codeforces 1058 D. Vasya and Triangle 分解因子

传送门&#xff1a;http://codeforces.com/contest/1058/problem/D 题意&#xff1a; 在一个n*m的格点中&#xff0c;问能否找到三个点&#xff0c;使得这三个点围成的三角形面积是矩形的1/k。 思路&#xff1a; 这个题就是找&#xff08;0&#xff0c;0&#xff09;&#xff0…