可变对象和不可变对象的差异
在 Java 中,不可变对象的 状态 在创建后不能被修改,但可以引用其他对象。它们在多线程环境中非常有用,因为多个线程无法更改对象的状态,因此不可变对象是线程安全的。不可变对象非常有助于避免时间耦合,并且始终具有故障原子性,并且在多线程中也很有用。为什么呢?因为没有人可以更改对象,对吧?所以,它变得线程安全,这意味着当程序的不同部分尝试访问该特定对象时,它不会导致任何意外问题。
另一方面,我们有可变对象,我们可以在任何状态下更改它们。它们字段可以在创建后更改。但正因为如此,它们不是线程安全的,在多线程程序中使用它们时,我们需要格外小心。
现在,让我们详细了解一下这两者之间的区别。
可变对象与不可变对象
关键 | 可变对象 | 不可变对象 |
---|---|---|
基本概念 | 我们可以在创建可变对象后修改其状态。例如,如果我们创建一个名为笔记本电脑的对象,带有品牌名称(如戴尔),然后更新品牌名称(如惠普)。 | 一旦创建了不可变对象,其状态就会被锁定,我们无法更改它。如果我们稍后需要设置不同的内容,则无需更改特定字段,而是需要创建一个新对象。 |
线程安全 | 可变对象不是线程安全的,这意味着如果多个线程同时尝试访问或修改该对象,可能会导致问题,因此我们需要提前注意它。 | 不可变对象是线程安全的。因为我们在创建后无法更改其状态,所以不同的线程可以访问该对象而不会出现任何干扰或意外行为。 |
最终类 | 可变类不需要是最终类。它可以通过其他子类扩展,并且其行为可以通过子类修改。 | 要创建不可变对象,请将类设为final。这可以防止任何人创建可能修改类行为并使其可变的子类。 |
示例 | 默认情况下,所有类及其对象本质上都是可变的。像ArrayList和HashMap这样的类允许在创建后更改其内容,这使得它们本质上是可变的。 | 在 Java 中,像String和包装类(如Integer和Boolean)这样的类是不可变类的示例。一旦创建,它们的状态以后就不能修改。 |
不可变类的示例
public final class ImmutableClass { private final String laptop; public ImmutableClass(String laptop) { this.laptop = laptop; } public String getLaptop() { return laptop; } } public class Main { public static void main(String[] args) { ImmutableClass immutableClass = new ImmutableClass("Dell"); System.out.println(immutableClass.getLaptop()); } }
输出
Dell
可变类的示例
public class MutableClass { private String laptop; public MutableClass(String laptop) { this.laptop = laptop; } public String getLaptop() { return laptop; } public void setLaptop(String laptop) { this.laptop = laptop; } } public class Main { public static void main(String[] args) { MutableClass mutableClass = new MutableClass("Dell"); System.out.println(mutableClass.getLaptop()); mutableClass.setLaptop("IBM"); System.out.println(mutableClass.getLaptop()); } }
输出
Dell IBM
广告