Java中的值类型:为什么它们不可变?
值類型不必是不變的。 但是他們是。
在上一篇文章中,我討論了Java中指針與引用之間的區別以及如何傳遞方法參數(按值傳遞或按引用傳遞)。 這些與Java中尚不存在的值類型密切相關(尚未)。
John Rose,Brian Goetz和Guy Steele 提出了一項建議 ,詳細介紹了值類型將如何/可能在Java中工作,并且還有一些不錯的文章。 我已經閱讀了我非常喜歡的“值類型:改造Java的類型系統” ,我建議閱讀。 如果建議過于密集,以至于您無法關注該主題,則可以先閱讀該文章。 它非常概括了背景,值類型是什么,優點,為什么Java不實現值類型是一個問題以及為什么它不是瑣碎的問題。 即使術語“值類型”也可以用來表示不同的東西,我也會在提案和文章中使用它。
我們如何傳遞參數與我們在變量中存儲什么
您可能還記得上一篇文章,我詳細介紹了Java根據引用的類型或引用或值傳遞方法參數:
- 當參數是對象時傳遞引用
- 參數為原始值時按值排序。
在原始帖子上以及在JCG重新發布 上都有一些評論,這些評論抱怨了我關于通過引用傳遞論點的術語。 注釋指出,參數始終按值傳遞,因為變量已包含對對象的引用。 但實際上,變量包含位。 即使了解我們如何想象這些位以及在交流時使用什么術語,這一點很重要。 我們可以說
如果我們遵循思想#1,則根據參數(對象或基元)的實際性質,參數傳遞是按值和/或按引用。 如果我們遵循思想#2,則變量將根據其類型的性質存儲參考和/或值。 我個人想寫的時候
Triangle triangle;則可變triangle是三角形,而不是對三角形的引用。 但這與我的大腦到底有什么關系并不重要。 在情況#1或#2中,對于類類型和基元有不同的方法。 如果我們在語言中引入值類型,則區別會變得更加普遍和易于理解。
值類型是不可變的
我解釋說,基于類型的隱式參數傳遞不會引起任何問題,因為基元是不可變的,因此,當作為方法參數傳遞時,即使通過引用傳遞它們也無法更改。 所以我們通常不在乎。 值類型沒有不同。 值類型也是不可變的,因為它們是值,并且值不變。 例如,PI的值為3.145926…,并且它永遠不會改變。
但是,這種不變性在編程中意味著什么? 值可以是實數,整數或復合值類型,它們在內存中均以位表示。 可以更改內存中的位(除非內存是ROM)。
在對象不可變的情況下,相當簡單。 宇宙中某個地方有一個我們無法改變的物體。 可能有許多保存對象的變量(對其有一個引用),并且代碼可以依賴于這樣的事實,即表示對象實際值的存儲位置中的位不變(或多或少)。
在值類型的情況下,這有點不同,并且這種差異是由于相同位在表示對象時對表示值類型的位的解釋不同。
值類型沒有身份
值類型沒有身份。 您不能有兩個保存值3 int變量并區分另一個。 它們具有相同的價值。 當類型更復雜時,也是如此。
假設我有一個具有兩個字段的值類型,例如
ValueType TwoFields {int count;double size;}說我有兩個變量
Twofields tF1 = new TwoFields(1,3.14)Twofields tF2 = new TwoFields(1,3.14)我不能從其他變量告訴tF1和tF2 。 如果他們的對象,他們是equals彼此但不==對方。 對于值類型,沒有==因為它們沒有身份。
如果TwoFields是不可變的類,我不能或不應該寫
TwoFields tF;...tF.count++;或一些類似的結構。 但我仍然可以寫
TwoFields tF;...tF = new TwoFields(tF.count+1, tF.size)使原始對象保持完整。 如果TwoFields是值類型,則無論哪種構造,都將創建一個新值。
值類型作為參數
值類型如何作為方法參數傳遞呢? 可能將值復制到參數變量。 可能會傳遞一些參考。 但是,這取決于編譯器(是Java還是其他語言)。 為什么?
- 值類型通常很小。 至少它們應該很小。 巨大的值類型失去了值類型提供的優點,但有缺點。
- 值類型是不可變的,因此像原語一樣復制它們沒有問題。 它們可以按值傳遞,就像“ Java中的所有值都按值傳遞”一樣。
- 它們沒有身份,不能引用它們。
但這不僅是將它們作為參數傳遞。 這也是分配變量的方式。 看代碼
Twofields tF1 = new TwoFields(1,3.14)Twofields tF2 = new TwoFields(1,3.14)比較一下
Twofields tF1 = new TwoFields(1,3.14)Twofields tF2 = tF1如果TwoFields是值類型,則兩個版本之間應該沒有區別。 它們必須產生相同的結果(盡管在編譯時可能不會通過相同的代碼)。 在這方面,參數傳遞和變量賦值之間沒有真正的區別。 即使實際變量作為位包含對存儲值的某些存儲位置的某些引用,也會復制值。
摘要
在我開始撰寫本文時:值類型不必是不變的。 這不是語言設計師決定的事情。 他們可以自由地實現可變的東西,但是在那種情況下,它將不是值類型。 值類型是不可變的。
翻譯自: https://www.javacodegeeks.com/2016/01/value-types-java-immutable.html
總結
以上是生活随笔為你收集整理的Java中的值类型:为什么它们不可变?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 应用程序 gui_Java G
- 下一篇: 碳酸钠的化学性质 主要有下面这些