值型別Java庫包AutoValue
Google釋出了值型別Java的開源庫包AutoValue 1.0。方便使用Java建立值型別。
什麼是值型別value type?
一個值型別物件value-typed object是指沒有標識的物件(注:類似DDD中的值物件),兩個值物件只有在它們內部狀態等同是才被認為等同,值物件是典型的不可變。
使用Java編寫一個值型別非常單調,為了幫助開發人員實現DRY原則,google提供了AutoValue庫包能夠產生值物件原始碼,你所要做的就是定義一個值型別抽象規格,AutVlue將完成剩餘的事情,產生你規格的具體實現類,這個實現包含值物件的各種屬性:hascode, equals, toString的實現,一個構造器能夠檢查前置條件,所有的必要的getter方法,因為值物件是不可變的,所以沒有setter方法。
AutoValue 是作為一個程式碼生成器,定義好你 的值型別規格後,一個註解處理器會在編譯時建立完整的值型別實現類。需要加入專案的編譯:
下面是一個複雜數字的值型別規格(抽象類):
注意到@AutoValue元註釋,其中定義了抽象的getter方法,為了建立值型別例項,我們定義了一個或更多靜態工廠方法,這裡提供了兩個工廠方法,工廠方法返回的是我們自己的抽象類,
當這個類第一次編譯AutoValue庫包建立下面的實現:
可見如果你自己編寫,需要很多單調的程式碼。
值得注意的是,第一次編譯會有編譯錯誤,因為在工廠方法中引用了AutoValue_Complex ,它第一次不存在,以後再次編譯就沒有問題了。
什麼是值型別value type?
一個值型別物件value-typed object是指沒有標識的物件(注:類似DDD中的值物件),兩個值物件只有在它們內部狀態等同是才被認為等同,值物件是典型的不可變。
使用Java編寫一個值型別非常單調,為了幫助開發人員實現DRY原則,google提供了AutoValue庫包能夠產生值物件原始碼,你所要做的就是定義一個值型別抽象規格,AutVlue將完成剩餘的事情,產生你規格的具體實現類,這個實現包含值物件的各種屬性:hascode, equals, toString的實現,一個構造器能夠檢查前置條件,所有的必要的getter方法,因為值物件是不可變的,所以沒有setter方法。
AutoValue 是作為一個程式碼生成器,定義好你 的值型別規格後,一個註解處理器會在編譯時建立完整的值型別實現類。需要加入專案的編譯:
<dependency> <groupId>com.google.auto.value</groupId> <artifactId>auto-value</artifactId> <version>1.0</version> <scope>provided</scope> </dependency> <p class="indent"> |
下面是一個複雜數字的值型別規格(抽象類):
import com.google.auto.value.AutoValue; @AutoValue public abstract class Complex { public static Complex createFromCartesian(double real, double imaginary) { return new AutoValue_Complex(real, imaginary); } public static Complex createFromPolar(double r, double theta) { return new AutoValue_Complex(r * Math.cos(theta), r * Math.sin(theta)); } public abstract double getReal(); public abstract double getImaginary(); } <p class="indent"> |
注意到@AutoValue元註釋,其中定義了抽象的getter方法,為了建立值型別例項,我們定義了一個或更多靜態工廠方法,這裡提供了兩個工廠方法,工廠方法返回的是我們自己的抽象類,
當這個類第一次編譯AutoValue庫包建立下面的實現:
import javax.annotation.Generated; @Generated("com.google.auto.value.processor.AutoValueProcessor") final class AutoValue_Complex extends Complex { private final double real; private final double imaginary; AutoValue_Complex( double real, double imaginary) { this.real = real; this.imaginary = imaginary; } @Override public double getReal() { return real; } @Override public double getImaginary() { return imaginary; } @Override public String toString() { return "Complex{" + "real=" + real + ", " + "imaginary=" + imaginary + "}"; } @Override public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof Complex) { Complex that = (Complex) o; return (Double.doubleToLongBits(this.real) == Double.doubleToLongBits(that.getReal())) && (Double.doubleToLongBits(this.imaginary) == Double.doubleToLongBits(that.getImaginary())); } return false; } @Override public int hashCode() { int h = 1; h *= 1000003; h ^= (Double.doubleToLongBits(real) >>> 32) ^ Double.doubleToLongBits(real); h *= 1000003; h ^= (Double.doubleToLongBits(imaginary) >>> 32) ^ Double.doubleToLongBits(imaginary); return h; } } <p class="indent"> |
可見如果你自己編寫,需要很多單調的程式碼。
值得注意的是,第一次編譯會有編譯錯誤,因為在工廠方法中引用了AutoValue_Complex ,它第一次不存在,以後再次編譯就沒有問題了。
相關文章
- Java基礎-基本型別和包裝型別Java型別
- 【Java】基本型別包裝類Java型別
- Java 包裝類和基本型別Java型別
- java基本型別和包裝型別的“==”和equals()方法Java型別
- java- 型別-轉換:基本型別以及包裝型別的轉換Java型別
- java基本資料型別包裝類Java資料型別
- 值型別和引用型別型別
- 值型別與引用型別型別
- 如何使用Java泛型對映不同的值型別Java泛型型別
- Java中基本資料型別和包裝型別有什麼區別?Java資料型別
- JavaScript值型別和引用型別JavaScript型別
- c#:值型別&引用型別C#型別
- Swift值型別和引用型別Swift型別
- Mysql資料庫學習(二):資料型別(數值型別 日期和時間型別 字串型別)MySql資料庫資料型別字串
- javascript基本型別 引用型別 基本包裝型別JavaScript型別
- 值型別與引用型別的區別型別
- C#的型別——值型別與引用型別C#型別
- JavaScript - 基本型別與引用型別值JavaScript型別
- MYSQL資料庫型別與JAVA型別對應關係MySql資料庫型別Java
- Java-API-基本資料型別包裝類JavaAPI資料型別
- (2)Java基本資料型別和包裝類Java資料型別
- 類似DDD的值物件的Java中新的值型別ValueType -jaxenter物件Java型別
- TypeScript 數值型別TypeScript型別
- Structs vs classes(值型別vs引用型別)Struct型別
- 【C#之值型別vs引用型別】C#型別
- javascript原始值和引用值型別及區別JavaScript型別
- Java 包裝類:原始資料型別與迭代器Java資料型別
- C#變數型別(1):引用型別和值型別 (轉)變數型別
- 【MySQL資料型別1之--數值型別】MySql資料型別
- C# 物件比較(值型別、引用型別)C#物件型別
- 區別值型別資料和引用型別資料型別
- 保留兩位小數:資料庫欄位型別NUMBER,Java欄位型別Double型別資料庫型別Java
- JavaScript - 變數、值、型別JavaScript變數型別
- Python數值型別Python型別
- CSS 顏色值型別CSS型別
- Swift Talk:理解值型別Swift型別
- js基本語法之 值型別(資料型別)(變數型別)JS資料型別變數
- C# 泛型 引用型別約束 值型別約束C#泛型型別