java不可变类型_Java中的值类型:为什么它们不可变?
java不可變類(lèi)型
值類(lèi)型不必是不變的。 但是他們是。
在上一篇文章中,我討論了Java中指針與引用之間的區(qū)別以及如何傳遞方法參數(shù)(按值傳遞或按引用傳遞)。 這些與Java中尚不存在的值類(lèi)型密切相關(guān)(尚未)。
John Rose,Brian Goetz和Guy Steele 提出了一個(gè)建議 ,詳細(xì)介紹了值類(lèi)型將如何/可能在Java中工作,并且還有一些很好的文章。 我已經(jīng)閱讀了我非常喜歡的“值類(lèi)型:改造Java的類(lèi)型系統(tǒng)” ,我建議閱讀。 如果建議過(guò)于密集,以至于您無(wú)法關(guān)注該主題,則可以先閱讀該文章。 它非常概括了背景,值類(lèi)型是什么,優(yōu)點(diǎn),為什么Java不實(shí)現(xiàn)值類(lèi)型是一個(gè)問(wèn)題以及為什么它不是瑣碎的問(wèn)題。 即使術(shù)語(yǔ)“值類(lèi)型”也可以用來(lái)表示不同的東西,我也會(huì)在提案和文章中使用它。
我們?nèi)绾蝹鬟f參數(shù)與我們?cè)谧兞恐写鎯?chǔ)什么
您可能還記得上一篇文章,我詳細(xì)介紹了Java根據(jù)參數(shù)的類(lèi)型按引用或按值傳遞方法參數(shù):
- 當(dāng)參數(shù)是對(duì)象時(shí)傳遞引用
- 參數(shù)為原始值時(shí)按值排序。
在原始帖子上以及在JCG重新發(fā)布 上都有一些評(píng)論,這些評(píng)論抱怨我關(guān)于通過(guò)引用傳遞論點(diǎn)的術(shù)語(yǔ)。 注釋指出,參數(shù)總是按值傳遞,因?yàn)樽兞恳寻瑢?duì)對(duì)象的引用。 實(shí)際上,變量包含位。 即使了解我們?nèi)绾蜗胂筮@些位以及在交流時(shí)使用什么術(shù)語(yǔ),這一點(diǎn)很重要。 我們可以說(shuō)
如果我們遵循思想#1,則根據(jù)參數(shù)(對(duì)象或基元)的實(shí)際性質(zhì),參數(shù)傳遞是按值和/或按引用。 如果我們遵循思想#2,則變量將根據(jù)其類(lèi)型的性質(zhì)存儲(chǔ)參考和/或值。 我個(gè)人想寫(xiě)的時(shí)候
Triangle triangle;則可變triangle是三角形,而不是對(duì)三角形的引用。 但這與我的大腦到底有什么關(guān)系并不重要。 在情況#1或#2中,對(duì)于類(lèi)類(lèi)型和基元都有不同的方法。 如果我們?cè)谡Z(yǔ)言中引入值類(lèi)型,則區(qū)別將變得更加普遍和易于理解。
值類(lèi)型是不可變的
我解釋說(shuō),基于類(lèi)型的隱式參數(shù)傳遞不會(huì)引起任何問(wèn)題,因?yàn)榛遣豢勺兊?#xff0c;因此,當(dāng)作為方法參數(shù)傳遞時(shí),即使通過(guò)引用傳遞它們也無(wú)法更改。 所以我們通常不在乎。 值類(lèi)型沒(méi)有不同。 值類(lèi)型也是不可變的,因?yàn)樗鼈兪侵?#xff0c;并且值不變。 例如,PI的值為3.145926…,并且它永遠(yuǎn)不會(huì)改變。
但是,這種不變性在編程中意味著什么? 值可以是實(shí)數(shù),整數(shù)或復(fù)合值類(lèi)型,它們?cè)趦?nèi)存中均以位表示。 可以更改內(nèi)存中的位(除非內(nèi)存是ROM)。
在對(duì)象不變的情況下,相當(dāng)簡(jiǎn)單。 宇宙中某個(gè)地方有一個(gè)我們無(wú)法改變的物體。 可能有許多保存對(duì)象的變量(對(duì)其有一個(gè)引用),并且代碼可以依賴(lài)于這樣的事實(shí),即表示對(duì)象實(shí)際值的存儲(chǔ)位置中的位不變(或多或少)。
在值類(lèi)型的情況下,這有點(diǎn)不同,并且這種差異是由于相同位在表示對(duì)象時(shí)對(duì)表示值類(lèi)型的位的解釋不同。
值類(lèi)型沒(méi)有身份
值類(lèi)型沒(méi)有身份。 您不能有兩個(gè)保存值3 int變量并區(qū)分另一個(gè)。 它們具有相同的價(jià)值。 當(dāng)類(lèi)型更復(fù)雜時(shí),也是如此。
假設(shè)我有一個(gè)具有兩個(gè)字段的值類(lèi)型,例如
ValueType TwoFields {int count;double size;}說(shuō)我有兩個(gè)變量
Twofields tF1 = new TwoFields(1,3.14)Twofields tF2 = new TwoFields(1,3.14)我不能告訴其他變量tF1和tF2 。 如果他們的對(duì)象,他們是equals彼此但不==對(duì)方。 對(duì)于值類(lèi)型,沒(méi)有==因?yàn)樗鼈儧](méi)有身份。
如果TwoFields是不可變的類(lèi),我不能或不應(yīng)該寫(xiě)
TwoFields tF;...tF.count++;或一些類(lèi)似的結(jié)構(gòu)。 但我仍然可以寫(xiě)
TwoFields tF;...tF = new TwoFields(tF.count+1, tF.size)保持原始對(duì)象不變。 如果TwoFields是值類(lèi)型,則無(wú)論哪種構(gòu)造,都將創(chuàng)建一個(gè)新值。
值類(lèi)型作為參數(shù)
值類(lèi)型如何作為方法參數(shù)傳遞呢? 可能將值復(fù)制到參數(shù)變量。 可能會(huì)傳遞一些參考。 但是,這取決于編譯器(是Java還是其他語(yǔ)言)。 為什么?
- 值類(lèi)型通常很小。 至少它們應(yīng)該很小。 巨大的值類(lèi)型失去了值類(lèi)型提供的優(yōu)點(diǎn),但有缺點(diǎn)。
- 值類(lèi)型是不可變的,因此像原始類(lèi)型一樣復(fù)制它們沒(méi)有問(wèn)題。 可以按值傳遞它們的方式與“ Java的所有內(nèi)容都按值傳遞”的方式相同。
- 它們沒(méi)有身份,不能引用它們。
但這不僅是將它們作為參數(shù)傳遞。 這也是分配變量的方式。 看代碼
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是值類(lèi)型,則兩個(gè)版本之間應(yīng)該沒(méi)有區(qū)別。 它們必須產(chǎn)生相同的結(jié)果(盡管在編譯時(shí)可能不會(huì)通過(guò)相同的代碼)。 在這方面,參數(shù)傳遞和變量賦值之間沒(méi)有真正的區(qū)別。 即使實(shí)際變量作為位包含對(duì)存儲(chǔ)值的某些存儲(chǔ)位置的某些引用,也會(huì)復(fù)制值。
摘要
在我開(kāi)始撰寫(xiě)本文時(shí):值類(lèi)型不必是不變的。 這不是語(yǔ)言設(shè)計(jì)師決定的事情。 他們可以自由地實(shí)現(xiàn)可變的東西,但是在那種情況下,它將不是值類(lèi)型。 值類(lèi)型是不可變的。
翻譯自: https://www.javacodegeeks.com/2016/01/value-types-java-immutable.html
java不可變類(lèi)型
總結(jié)
以上是生活随笔為你收集整理的java不可变类型_Java中的值类型:为什么它们不可变?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: sql 解析 java_将Java 8流
- 下一篇: DDOS还原(ddos还)