我们可以创建一个包含可变对象的Immutable对象吗?有可能吗? 请让我更清楚这一点。
提前致谢。
答案 0 :(得分:2)
是的,我们可以。
以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
字段,但只要它没有泄露,就可以安全。所以如果我们仔细关注design strategy,答案是肯定的。
答案 1 :(得分:1)
在Java中(据我所知,所有其他主流语言都带有const
/ final
/ readyonly
/ val
等关键字)"不可变& #34; object可以包含对可变对象的引用。要更深入地了解不变性,请参阅this paper - 快速介绍的是,有非官方的Java扩展允许您指定例如不可变对象只能包含对不可变对象的引用,例如Javari或Joe3或OIGJ
答案 2 :(得分:0)
Java中的对象永远不会包含其他对象 - 不像在C或其他一些编程语言中那样。甚至所谓的“容器”类实际上只包含引用到其他对象。
不可变对象可以引用任何其他对象,可变或不可变。
您不能更改不可变对象引用的其他对象,但如果它们是可变的,您可以更改其他对象。
答案 3 :(得分:0)
编辑:这在某种程度上取决于“不可变”的含义。正如另一个人所指出的,有时“不可变”被定义为“浅”不变性的形式 - 即允许对可变对象的持续引用。我自己并不喜欢这个定义。有些人可能在这里不同意我(并且希望没有人会对不同意见的b / c进行投票),我认为将“不变性”定义为“没有任何形式的可变状态”会更清楚。
根据这个定义,你的问题的答案是** no *因为如果它引用了可变对象,它赋予它可变状态,这会使对象本身变得可变。
我认为在这一点上区分常量引用或指针和不可变对象非常重要。例如,以下代码是对常量对象的常量引用:
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)引用可变对象的对象是否仍然可以被认为是不可变的取决于你对“不可变”的定义。在我看来它不能因为引用一个可变对象赋予它可变状态;最好将其描述为不可变的,这会令人困惑/误导。
答案 4 :(得分:-1)
我认为这是可能的。但是引用可变对象的变量的访问修饰符必须是最终的。