[英]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.