不可变类? [英] Immutable class?

查看:33
本文介绍了不可变类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使 Java 类不可变,什么是不可变性的需要,使用它有什么好处?

How can one make a Java class immutable, what is the need of immutability and is there any advantage to using this?

推荐答案

什么是不可变对象?

不可变对象是实例化后不会改变状态的对象.

An immutable object is one that will not change state after it is instantiated.

如何使对象不可变?

一般来说,不可变对象可以通过定义一个没有暴露任何成员并且没有任何 setter 的类来创建.

In general, an immutable object can be made by defining a class which does not have any of its members exposed, and does not have any setters.

以下类将创建一个不可变对象:

The following class will create an immutable object:

class ImmutableInt {
  private final int value;

  public ImmutableInt(int i) {
    value = i;
  }

  public int getValue() {
    return value;
  }
}

从上面的例子可以看出,ImmutableInt的值只能在对象实例化时设置,并且只有一个getter(getValue)实例化后对象的状态不能改变.

As can be seen in the above example, the value of the ImmutableInt can only be set when the object is instantiated, and by having only a getter (getValue) the object's state cannot be changed after instantiation.

但是,必须注意对象引用的所有对象也必须是不可变的,否则可能会更改对象的状态.

However, there must be care taken that all objects that are referenced by the object must be immutable as well, or it could be possible to change the state of the object.

例如,允许通过 getter 获取对数组或 ArrayList 的引用将允许通过更改数组或集合来更改内部状态:

For example, allowing an reference to an array or ArrayList to be obtained through an getter will allow the internal state to change by changing the array or collection:

class NotQuiteImmutableList<T> {
  private final List<T> list;

  public NotQuiteImmutableList(List<T> list) {
    // creates a new ArrayList and keeps a reference to it.
    this.list = new ArrayList(list); 
  }

  public List<T> getList() {
    return list;
  }
}

上面代码的问题是,ArrayList可以通过getList获取并被操作,导致对象本身的状态被改变,因此, 不是一成不变的.

The problem with the above code is, that the ArrayList can be obtained through getList and be manipulated, leading to the state of the object itself to be altered, therefore, not immutable.

// notQuiteImmutableList contains "a", "b", "c"
List<String> notQuiteImmutableList= new NotQuiteImmutableList(Arrays.asList("a", "b", "c"));

// now the list contains "a", "b", "c", "d" -- this list is mutable.
notQuiteImmutableList.getList().add("d");

解决此问题的一种方法是在从 getter 调用时返回数组或集合的副本:

One way to get around this problem is to return a copy of an array or collection when called from a getter:

public List<T> getList() {
  // return a copy of the list so the internal state cannot be altered
  return new ArrayList(list);
}

不变性的优势是什么?

不变性的优势来自于并发.在可变对象中很难保持正确性,因为多个线程可能会尝试更改同一对象的状态,导致某些线程看到同一对象的不同状态,具体取决于对所述对象的读取和写入时间对象.

The advantage of immutability comes with concurrency. It is difficult to maintain correctness in mutable objects, as multiple threads could be trying to change the state of the same object, leading to some threads seeing a different state of the same object, depending on the timing of the reads and writes to the said object.

通过拥有一个不可变对象,可以确保所有正在查看该对象的线程都会看到相同的状态,因为不可变对象的状态不会改变.

By having an immutable object, one can ensure that all threads that are looking at the object will be seeing the same state, as the state of an immutable object will not change.

这篇关于不可变类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆