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

01_*_*1__ 0 java string static final immutability

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

Nat*_*hes 5

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

final List<String> list = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

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

list.add("asdf");
Run Code Online (Sandbox Code Playgroud)

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

(使用static只表示字段是在类上定义的,而不是在实例上定义的.它用于定义常量值(更多是在添加枚举之前),但仅仅因为类只需要一个值.static关键字与不变性.)

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

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

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

另外,不可变对象更安全,请参阅实践中的Java Concurrency,3.4:

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