当前位置: 首页 > 知识库问答 >
问题:

像String这样的不可变对象而不是仅仅使用静态final的实际好处是什么?[副本]

左丘边浩
2023-03-14

我的意思是,为什么事实上不可变的对象存在?为什么我们不只是使用最后的静态修饰符呢?字符串有什么重要的地方让Java使其不可变?

共有1个答案

阮鸿煊
2023-03-14

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

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

我不能将列表换出另一个列表,但我仍然可以修改列表的内容:

list.add("asdf");

但是一个不可变的对象一旦被构造就不能被改变。

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

不可变对象是线程安全的,对于内存可见性、丢失更新等的关注是不适用的,因为对象的状态在构造时是安全发布的。

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

如果您有一个可变对象,其中一个可变字段参与了它的equals和hashCode实现,那么您可能会出现这样的情况:您将它放在一个集合中,然后更改该字段,从而破坏集合的工作方式。最好事先避免那种事。

此外,共享不可变对象更安全,请参阅Java并发在实践,3.4:

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

 类似资料:
  • 本文向大家介绍Java 中的 String对象为什么是不可变的,包括了Java 中的 String对象为什么是不可变的的使用技巧和注意事项,需要的朋友参考一下 什么是不可变对象? String对象是不可变的,但这仅意味着你无法通过调用它的公有方法来改变它的值。 众所周知, 在Java中, String类是不可变的。那么到底什么是不可变的对象呢? 可以这样认为:如果一个对象,在它创建完成之后,不能再

  • 当我在写这段代码时,我得到了一个编译时错误,它说:“lambdas中的变量必须是final或实际上是final”。

  • 本文向大家介绍String 为什 么是不可变的?相关面试题,主要包含被问及String 为什 么是不可变的?时的应答技巧和注意事项,需要的朋友参考一下 简单的来说:String 类中使用 final 关键字修饰字符数组来保存字符串,`private final char value[]`,所以 String 对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 Ab

  • 这个问题在这里已经有了答案: > 为什么匿名类只能访问最终变量? 为什么对于实例变量[重复]忽略“Lambda表达式中使用的变量必须是final或实际上是final”警告 “lambda在start方法参数被垃圾回收后才能运行”是什么意思? 为什么要复制?

  • 问题内容: 我是一个相对较新的QA工程师,致力于学习Selenium(使用Java),并且我想使用页面对象为页面建模。 目前,我的页面对象类是静态变量(用于定位页面元素的对象)和静态方法(用于获取By对象并执行页面功能)的集合。这对我来说似乎是最简单的方法,因为我的方法不需要依赖任何实例变量,而只需依赖定位符。 我只是在测试代码中根据需要调用这些方法。 但是,我读到的有关页面对象的所有内容都涉及实

  • 下面是一个不可变类的示例: 下面是类的实现: 当我创建的实例时,我正在的构造函数中对进行深度复制,但是我能够通过更新的值,这种方法破坏了my类的不变性。我在这里做错了什么?