不可变对象(如String)的实际好处是什么,而不是仅使用静态final?

时间:2015-10-15 14:55:39

标签: java string static immutability final

我的意思是,为什么存在defacto不可变对象?为什么我们不只是使用最终的静态修饰符?关于String,Java使它变得不可变的重要性是什么?

2 个答案:

答案 0 :(得分:5)

使变量最终使得该引用不可更改。但是参考指向的对象仍然可以改变,所以如果我定义:

final List<String> list = new ArrayList<String>();

我无法将列表换成另一个列表,但我仍然可以修改列表的内容:

list.add("asdf");

但是一旦构造了不可变对象,就不能改变它。

(使用static只意味着字段是在类上定义的,而不是在实例上定义的。它用于定义常量值(更多是在添加枚举之前),但仅仅因为类只需要一个值。静态关键字不是与不变性直接相关。)

不可变对象是线程安全的,并且对内存可见性,丢失更新等的担忧不适用,因为对象的状态在构造时安全地发布。

他们很容易推理,因为没有状态变化。对于具有基于价值的平等的事物,不变性是所描述概念的更好匹配。对于字符串和数字,这是不变的抽象,不变性是特别合适的。

如果你有一个可变对象,其中一个可变字段参与了它的equals和hashCode实现,那么你可以将它放在一个集合中,然后改变字段,破坏集合的工作方式。最好事先避免这种事情。

同样不可变的对象分享更安全,参见 Java Concurrency in Practice ,3.4:

  

不可变对象也更安全。将可变对象传递给不受信任的代码,或以其他方式将其发布到不受信任的代码可以找到它的地方是危险的 - 不受信任的代码可能会修改其状态,或者更糟糕的是,保留对它的引用并稍后从另一个线程修改其状态。另一方面,不可变对象不能以恶意或错误的代码以这种方式被破坏,因此它们可以安全地自由共享和发布而无需制作防御性副本。

答案 1 :(得分:0)

最终静态变量 - &gt;该课程的一个实例。你无法改变。支持多线程。 不可变对象 - &gt;每个类都有其实例变量。你可以改变。支持多线程。