類似DDD的值物件的Java中新的值型別ValueType -jaxenter

banq發表於2019-11-07

值型別與普通型別物件的不同之處在於:值型別沒有物件標頭或標識,沒有對值型別的引用,值型別是不可變的,並且值型別之間沒有繼承,因此,它沒有多型性。是不是非常類似DDD的值物件?

沒有標識

類似原始變數型別byte,char,short,int,long,float,double或者Boolean,沒有任何標識,不像普通物件都有標識,需要使用equals()方法去比較它們。

沒有引用

值儲存在變數中,而不儲存在堆heap中。當將值型別作為引數傳遞給方法時,該方法將接收原始值型別的“副本”,這是因為Java通過值而不是通過引用傳遞所有引數。隨著值型別的引入,這不會改變。將值型別作為引數傳遞給方法呼叫時,該值型別的所有位都將複製到該方法的本地引數變數中。

沒有物件頭部

由於值型別是值,儲存在變數中而不是堆中,因此它們不需要標頭。編譯器僅知道變數的型別,程式應以何種方式處理該變數中的bit位即可。類似原始型別一樣,當我們建立一個值型別的陣列時,這些值將一個接一個地包裝在記憶體中。這意味著對於值型別,我們將不會遇到物件陣列所具有的問題。沒有對陣列中各個元素的引用,它們不能分散在記憶體中。當CPU載入第一個元素時,它將載入同一記憶體頁面上的所有元素,並且訪問連續元素將利用處理器快取的優勢。

沒有繼承

值型別之間可能存在繼承,但是編譯器將很難管理它,並且不會帶來很多好處。我敢說允許繼承不僅會給編譯器造成問題,還會誘使沒有經驗的程式設計師建立弊大於利的構造。在即將釋出的支援值型別的Java版本中,值型別之間或類與值型別之間將沒有繼承。這是一個設計決策。

沒有多型

由於沒有繼承,因此不能有值型別多型性。但是,還有更多的原因表明對值型別實現多型是不合理的。

不變性

不變性是設計決定,但這是自然的方式。Java中的值型別是不可變的。不變性通常是一件好事。不可變物件有很大的幫助,在清潔和執行緒安全的方式編碼。不變性並不能解決所有的問題,但很多時候更是得心應手。

如果您考慮int作為一個數字,很明顯您不能更改其值。如果變數保留整數值2,則可以更改儲存在變數中的值,但不能將值本身更改為3。

您可以更改儲存值型別的變數的內容,但不能更改值型別本身。當您更改某個位時,實際上,根據哲學,您建立了一個新的值型別並儲存了新值來代替舊值。

不變性是一種特性,它與不能引用值型別這一事實密切相關。從理論上講,Java可以允許我們修改值型別的欄位。結果本質上是相同的:我們獲得了不同的值。這樣,在值型別的情況下不變性不受限制。這僅取決於我們如何編寫程式以及如何考慮值型別。將它們視為諸如數字之類的價值,本質上是不變的,被認為是一種健康的思維方式。

玩耍

在JEP 169下的Valhalla專案中,正在為Java開發值型別。目前,有一個早期訪問版本可以嘗試。此版本是Java 11版本的Java分支,並且有一些限制。您可以下載早期訪問版本。JEP主頁是https://openjdk.java.net/jeps/169,您可以從https://jdk.java.net/valhalla/下載EA版本。

您可以嘗試使用Eclipse,IntelliJ或記事本來編輯原始碼,但至少在IntelliJ 2019.EA版中,我無法構建程式碼。即使該程式碼是Java 11的原始碼,IntelliJ仍將其識別為Java 13,這順便說一句,暗示了我們可以期望發行版本中的值型別。可以手動執行命令列javac命令,然後手動java啟動JVM命令來完成程式碼的編譯。即使我對Maven的瞭解比對ANT的熟悉,我仍可以設法與IntelliJ提取的ANT指令碼相處。

總結

Java發展迅速。在過去的兩年中出現了許多新事物,並且正在醞釀中的許多新事物將在未來提供。值型別功能是其中之一。本文介紹了此功能的主要特徵,並簡要介紹了這項新技術。Java還是一種主要的程式語言,也許它是在專業環境中僅次於COBOL的第二廣泛使用的程式語言。

更詳細情況點選標題見原文。

相關文章