AutoValue:生成的不可变值类
Google GitHub托管的項(xiàng)目AutoValue之所以有趣,有多種原因。 該項(xiàng)目不僅使為“ 值對(duì)象 ”編寫更少的Java代碼變得容易,而且還為Java注釋處理的實(shí)際應(yīng)用提供了概念上簡(jiǎn)單的演示。 該自動(dòng)/值項(xiàng)目是由提供谷歌的員工凱文Bourrillion和埃蒙·麥克馬納斯和許可與Apache的版本2的許可 。
《 AutoValue用戶指南》簡(jiǎn)短明了,其簡(jiǎn)潔性反映了項(xiàng)目本身。 用戶指南提供了使用AutoValue的簡(jiǎn)單示例,討論了為什么需要 AutoValue,在“ 我如何……”部分中回答了常見問題,并概述了與使用AutoValue有關(guān)的一些最佳做法 。
以下代碼清單包含一個(gè)我手寫的簡(jiǎn)單類,稱為Person 。 編寫此類時(shí)要牢記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(); }當(dāng)使用AutoValue生成完整的“值類”時(shí),只需為AutoValue提供一個(gè)抽象類(故意不支持接口)以生成相應(yīng)的具體擴(kuò)展。 該abstract類必須使用@AutoValue注釋進(jìn)行注釋,必須提供提供值類實(shí)例的static方法,并且必須提供暗示值類的受支持字段的public或包范圍的abstract訪問器方法。
在上面的代碼清單中,靜態(tài)實(shí)例創(chuàng)建方法實(shí)例化了AutoValue_Person對(duì)象,但是我沒有定義這樣的AutoValue_Person類。 此類是AutoValue生成的類的名稱,該類將在對(duì)Person.java進(jìn)行javac編譯時(shí)執(zhí)行AutoValue的注釋處理時(shí)生成。 由此,我們可以看到AutoValue生成的類的命名約定: AutoValue_放在源類的名稱之前,以形成生成的類的名稱。
當(dāng)Person.java在編譯過程中應(yīng)用AutoValue注釋處理進(jìn)行編譯時(shí),將生成生成的類。 就我而言(使用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;}}通過檢查生成的代碼可以得出以下幾點(diǎn)結(jié)論:
- 生成的類擴(kuò)展(實(shí)現(xiàn)繼承)了手寫的抽象類,從而允許使用代碼使用手寫類的API,而不必知道正在使用生成的類。
- 即使沒有在源類中直接定義任何字段,也將生成字段; AutoValue解釋了提供的abstract訪問器方法中的字段。
- 生成的類不為字段提供“設(shè)置” / mutator方法(get / accessor方法)。 這是AutoValue的故意設(shè)計(jì)決策 ,因?yàn)閂alue Objects的關(guān)鍵概念是它們是不可變的。
- 考慮到每個(gè)字段的類型,將自動(dòng)為每個(gè)字段適當(dāng)?shù)厣蒭quals(Object) , hashCode()和toString()的實(shí)現(xiàn)。
- 在源類和方法上的Javadoc注釋不會(huì)在生成的擴(kuò)展類上重現(xiàn)。
使用諸如AutoValue生成之類的方法的主要優(yōu)點(diǎn)之一是,開發(fā)人員可以將精力集中在特定類應(yīng)支持的更高級(jí)的概念上,并且代碼生成可確保一致,正確地實(shí)現(xiàn)較低級(jí)別的細(xì)節(jié)。 但是,使用這種方法時(shí)需要牢記一些注意事項(xiàng),該文檔的“ 最佳實(shí)踐”部分是一個(gè)不錯(cuò)的地方,可以讓您早日閱讀一下以了解AutoValue的假設(shè)是否適合您的情況。
- 當(dāng)開發(fā)人員受過足夠的訓(xùn)練以查看和維護(hù)abstract “源” Java類而不是生成的類時(shí),AutoValue最有可能會(huì)有所幫助。
- 下次注釋處理再次生成該類時(shí),對(duì)生成類的更改將被覆蓋,否則必須停止該類的生成,以免發(fā)生這種情況。
- 您將需要設(shè)置build / IDE,以便將生成的類視為“源代碼”,以便abstract類可以編譯。
- 如果將可變字段與AutoValue一起使用時(shí),如果要保持不變性,則必須格外小心(通常選擇使用Value Objects時(shí)就是這種情況)。
- 查看“ 最佳實(shí)踐”和“我如何……”部分,以確保沒有任何AutoValue的設(shè)計(jì)假設(shè)使它不利于您的需求。
結(jié)論
AutoValue允許開發(fā)人員編寫更簡(jiǎn)潔的代碼,重點(diǎn)放在高級(jí)細(xì)節(jié)上,并將繁瑣的低級(jí)(通常是容易出錯(cuò)的)細(xì)節(jié)的實(shí)現(xiàn)委派給AutoValue,以自動(dòng)生成代碼。 這類似于IDE的源代碼生成可以執(zhí)行的操作,但是AutoValue相對(duì)于IDE方法的優(yōu)勢(shì)在于,AutoValue可以在每次編譯代碼時(shí)重新生成源代碼,從而使生成的代碼保持最新。 AutoValue的這一優(yōu)勢(shì)也是Java自定義注釋處理功能強(qiáng)大的一個(gè)很好的例子。
翻譯自: https://www.javacodegeeks.com/2016/06/autovalue-generated-immutable-value-classes.html
總結(jié)
以上是生活随笔為你收集整理的AutoValue:生成的不可变值类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: junit rule_使用JUnit的E
- 下一篇: ddos流量攻击与防御的关系(ddos流