我对此感到困惑,因为在内部有一个 final 字段b
只是type B
确保Object A
该字段 b
不能再次实例化,但A
仍然可以通过b
内部或外部操作来更改其状态,那么 final 在这里如何达到不可变的目的?
5 回答
对你最后一个问题的简单回答是:它没有。
除非没有办法改变 'b' 的状态,否则 final 在 'a' 的可变性方面不会给你带来任何好处。
这些是正交概念,但是在所有可能的地方使用“final”将帮助您实现对象不变性,尽管这不是必需的,您也可以不用。
final
有助于实现不可变对象。不可变对象必须确保它拥有的任何对象本身都是不可变的,或者至少不是公开可变的。
Java 中没有通向不变性的王道(或者,我可能会补充)。
制作该字段final
提供了一个编译时检查,即 A 没有修改对 B的引用。
虽然这不足以保证 A 的不变性,但它是有帮助的。
防御性副本可以防止对 b 引用的可变对象进行外部修改。可以为 A 构造函数接收的对象和 A 访问器返回的对象制作防御性副本。
我不是 100% 确定,但我认为本质上的区别在于,使用final
关键字只是向程序员保证,变量将在整个执行过程中始终引用同一个对象。然而,没有什么能阻止对象本身以某种方式发生变化。
考虑以下伪代码:final Car c = new BMW(Color.Green, new Milage(0));
您不能c
稍后在代码中分配给奥迪或福特,但“使用”您的宝马没有限制,因此它的里程会在您的程序过程中增加。
对象是不可变的 - 意味着该对象中变量的数据或值一旦设置就无法更改。
引用是不可变的 - 意味着指向该对象的变量是最终变量。