[英]Java Mutable and Immutable concepts
我們可以創建一個包含可變對象的不可變對象嗎? 有可能嗎? 請讓我對此更加清楚。
提前致謝。
我們可以。
以java.lang.String
的代碼為例:
/** The value is used for character storage. **/
private final char value[];
顯然,數組是可變的,因為我們可以像這樣輕松地更改其內容:
value[0] = '&';
但是String
仍然是不變的。 也就是說,一旦創建,其內容將永遠不會改變。 怎么發生的?
因為即使value
是可變的, String
的用戶也沒有“常規”方式來修改它:
value
宣布為private final
。 而且String
本身是final
,意味着沒有子類。 value
方法。 value
字段也可以由多個String
實例共享,但是只要不泄漏就可以了。 因此,如果我們認真遵循設計策略 ,答案是肯定的。
Java中的對象從不真正包含其他對象-不像C或某些其他編程語言那樣。 甚至所謂的“容器”類實際上只包含對其他對象的引用 。
不可變的對象可以引用任何其他可變或不可變的對象。
您不能更改不可變對象所引用的其他對象,但是可以更改其他對象的可變對象。
編輯 :這在某種程度上取決於您所說的“不變”。 正如另一個人指出的那樣,有時將“不變”定義為“淺”不變性的一種形式,即允許對可變對象的不變引用。 我自己不喜歡這個定義。 這里有些人可能不同意我的觀點(希望沒有人會反對意見分歧),我認為將“不變性”定義為“沒有任何可變的狀態”更為明確。
在此定義下,您的問題的答案為“否”,因為如果它引用的可變對象具有可變的狀態,則該可變的對象本身就是可變的。
我認為在這一點上區分常量引用或指針與不可變對象很重要 。 例如,以下代碼是對常量對象的常量引用:
private final string abc = "John";
請注意,您無法修改“ abc”的狀態(即該特定字符串始終為“ John”-您以后無法將其更改為“ Johnny”,則需要創建一個新字符串。此外,您也可以不能用新字符串替換“ John”(即變量“ abc”本身將始終引用該字符串)。
以下代碼是對不可變對象的可變引用:
public string abc = "John";
(順便說一句,我確實意識到您應該在此處使用屬性)。
如果您以后要執行以下操作:
abc = "Johnny";
您將被允許這樣做。 在這種情況下,您要更改變量“ abc”所引用的對象,而不是原始字符串。 只要存在,字符串“ John”將始終具有該值。
但是,請考慮以下對象:
public class Defg
{
public int Count;
public Defg(int Count)
{
this.Count = Count;
}
}
顯然,這是一個可變的類(因為您可以更改“ Count”的值)。
您可以執行以下操作:
// Mutable reference to a mutable object. Note: "Count: 1" is a bit of C# syntax that just means that the "Count" parameter is set to 1. It's not strictly necessary here, I just added it for clarity.
public Defg Mutable = new Defg(Count: 1);
// Constant reference to a mutable object
public final Defg ConstReference = new Defg(Count: 1);
請注意,以下全部完全正確:
Mutable = new Defg(Count: 10);
Mutable.Count = 4;
ConstReference.Count = 3;
但是,您不能執行以下操作:
ConstReference = new Defg(Count: 3);
請特別注意,Defg 不可能是不可變的對象,因為可以更改其狀態。
總結一下:
a)完全可以使用對常量對象的可變引用或對可變對象的常量引用-對該對象的引用的可變性與對象本身是否可變無關, 反之亦然 。
b)引用可變對象的對象是否仍然可以視為不可變取決於您對“不可變”的定義。 在我看來,這不是因為引用可變對象會導致其可變狀態。 將其描述為不可變的充其量只能是令人困惑/誤導。
我認為這是可能的。 但是引用可變對象的變量的訪問修飾符必須是最終的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.