如何维护引用可变对象的类的不可变性质?

时间:2018-07-07 17:50:13

标签: java immutability

我很清楚使类成为不可变的规则。但是考虑一下这样的情况:我的A类组成B类。B类在外部jar中,而B类再次组成C和D,即。

class A{
  B b;
}
// External library
class B{
  C c;
  D d;
}
class C{
}
class D{
}

如果我不能在外部库中修改类,如何使A类不可变?如果外部lib中的类是可修改的,那么我可以实现可克隆的,但这是不可能的,因为我无法对其进行修改。

2 个答案:

答案 0 :(得分:1)

您应该为可变实例创建防御性副本:

class A {

    private final B b;

    public A(B b) {
        // Create a defensive copy of b
        this.b = new B(b);
    }
}

如果B没有提供这样的副本构造函数,则您将需要自行为B实现防御性复制。

如果您不这样做,我可以将B的实例传递给A,但也可以将B的实例保留给我自己,并在以后自行对其进行突变会。

答案 1 :(得分:0)

A类不应允许访问任何可变引用。

这是您的班级示例的样子:

class A {

  private final B b;

  public A(B b) {
    this.b = b;
  }

  // no public access to B reference that's final.  No changing it from the outside.  A is immutable.
}

类B,C和D来自库。如果给A一个可变的引用并允许其余代码更改B或其C和D子代的状态,则无需执行任何操作。但是,如果您正确构造B并将其委托给A,那么其他人将无法更改其状态。