【问题标题】:Is there a way to create an Immutable object in java, when the object have mutators?有没有办法在 java 中创建一个不可变对象,当对象有 mutators 时?
【发布时间】:2015-03-13 16:35:17
【问题描述】:

这段代码很熟悉。

List<Character> list = new ArrayList<Character>();

  // populate the list
  list.add('X');
  list.add('Y');


  // make the list unmodifiable
  List<Character> immutablelist = Collections.unmodifiableList(list);

现在我有一个带有变量、getter 和 setter 的典型模型类。在我调用了我想要的设置器之后,我可以使那个对象不可变吗?这样的事情是我的梦想......

Person person = new Person();
person.setFirstName("firsName");
person.setLastname("lastName");
// i have a lot to set!!- Person is pretty large

// some way to do this
Person stubborn = Object.immutableObject(person);

我知道没有 Object.immutableObject()..但是有可能实现这样的事情吗??

【问题讨论】:

  • 没有办法完全按照列表​​实现的方式进行操作 - 但您也可以克隆对象。这样,如果新对象被修改,则原始对象不会被修改。
  • 注意与-如何在Java中创建不可变对象?我希望对象是可变的 - 但有时我可能会决定,我已经完成了必要的编辑 - 不应该进行更多的编辑。

标签: java


【解决方案1】:

没有获得这种行为的通用方法。

您可以使用构造函数创建一个 ImmutablePerson 类,该构造函数将接受 Person 并构造该 Person 的不可变版本。

【讨论】:

  • 这是一种比截断突变体更清洁、更安全的方法。为了提高可用性,Person 可能应该扩展 ImmutablePerson 或者——甚至更好——两者都应该实现一个通用接口。
【解决方案2】:

不做一些工作就没有办法做到这一点。

您需要按照 Eran 的建议通过从可变对象创建新的不可变对象来进行编译时检查,添加一些代码进行运行时检查,或者使用拆分接口进行较弱的编译器时间检查 例如

interface ReadOnlyPerson {
  int getX();
} 

interface ModifiablePerson extends ReadOnlyPerson{    
   void setX();
}

class Person implements ModifiablePerson {
}

然后您可以在构造后传递不可变引用。

但是这种模式并不能保证对象不会被修改,因为可以强制转换 ReadOnlyPerson 引用等。

【讨论】:

    【解决方案3】:

    当然,只要在 Person 对象中有一个布尔标志,它表示对象是否被锁定以进行修改。如果它被锁定,则让所有设置者什么都不做或让他们抛出异常。

    调用immutableObject(person) 时只需将标志设置为true。设置标志也将锁定/拒绝以后设置/更改标志的能力。

    【讨论】:

      猜你喜欢
      • 2015-03-28
      • 1970-01-01
      • 2022-11-22
      • 2019-03-02
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 2015-08-25
      相关资源
      最近更新 更多