使用 String 这样的不可变对象而不是仅仅使用 static final 的实际好处是什么?
What is the actual benefit of immutable objects like String instead of using just static final?
我的意思是,为什么存在事实上的不可变对象?为什么我们不直接使用 final static 修饰符? Java 使 String 不可变的重要之处是什么?
最终静态变量 -> class 的一个实例。你不能改变。支持多线程。
不可变对象 -> 每个 class 都有它的实例变量。你可以改变。支持多线程。
将变量设置为 final 会使该引用不可更改。但是引用指向的对象仍然可以改变,所以如果我定义:
final List<String> list = new ArrayList<String>();
我无法将列表换成另一个列表,但我仍然可以修改列表的内容:
list.add("asdf");
但是不可变对象一旦构造就无法更改。
(仅使用静态意味着该字段是在 class 上定义的,而不是在实例上定义的。它用于定义常量值(在添加枚举之前更多)但只是因为只需要一个值class。static 关键字与不变性没有直接关系。)
不可变对象是线程安全的,内存可见性、丢失更新等问题不适用,因为对象的状态在构造时安全发布。
它们很容易推理,因为没有状态变化。对于基于价值的平等事物,不变性更符合所描述的概念。对于不变的抽象字符串和数字,不变性尤其合适。
如果您有一个可变对象,其中可变字段参与其 equals 和 hashCode 实现,那么您可能会遇到这样的情况:将其放入集合中,然后改变字段,破坏集合的工作方式。最好提前避免这种事情。
不可变对象也更安全地共享,请参阅 Java Concurrency in Practice、3.4:
Immutable objects are also safer. Passing a mutable object to untrusted code, or otherwise publishing it where untrusted code could find it, is dangerous -- the untrusted code might modify its state, or worse, retain a reference to it and modify its state later from another thread. On the other hand, immutable objects cannot be subverted in this manner by malicious or buggy code, so they are safe to share and publish freely without the need to make defensive copies.
我的意思是,为什么存在事实上的不可变对象?为什么我们不直接使用 final static 修饰符? Java 使 String 不可变的重要之处是什么?
最终静态变量 -> class 的一个实例。你不能改变。支持多线程。 不可变对象 -> 每个 class 都有它的实例变量。你可以改变。支持多线程。
将变量设置为 final 会使该引用不可更改。但是引用指向的对象仍然可以改变,所以如果我定义:
final List<String> list = new ArrayList<String>();
我无法将列表换成另一个列表,但我仍然可以修改列表的内容:
list.add("asdf");
但是不可变对象一旦构造就无法更改。
(仅使用静态意味着该字段是在 class 上定义的,而不是在实例上定义的。它用于定义常量值(在添加枚举之前更多)但只是因为只需要一个值class。static 关键字与不变性没有直接关系。)
不可变对象是线程安全的,内存可见性、丢失更新等问题不适用,因为对象的状态在构造时安全发布。
它们很容易推理,因为没有状态变化。对于基于价值的平等事物,不变性更符合所描述的概念。对于不变的抽象字符串和数字,不变性尤其合适。
如果您有一个可变对象,其中可变字段参与其 equals 和 hashCode 实现,那么您可能会遇到这样的情况:将其放入集合中,然后改变字段,破坏集合的工作方式。最好提前避免这种事情。
不可变对象也更安全地共享,请参阅 Java Concurrency in Practice、3.4:
Immutable objects are also safer. Passing a mutable object to untrusted code, or otherwise publishing it where untrusted code could find it, is dangerous -- the untrusted code might modify its state, or worse, retain a reference to it and modify its state later from another thread. On the other hand, immutable objects cannot be subverted in this manner by malicious or buggy code, so they are safe to share and publish freely without the need to make defensive copies.