Ankit Pandoh
Ankit Pandoh

Reputation: 577

How to maintain Immutable nature of a class referencing Mutable Objects?

I am well aware of rules to make a class Immutable. But Consider a situation where my class A which compose class B. Class B is in external jar and Class B again compose of C and D i.e.

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

How can I make class A Immutable if I can't modify classes in External lib? If classes in External lib were modifiable, I could have implement cloneable but this is not possible since I can't modify them.

Upvotes: 0

Views: 100

Answers (2)

lexicore
lexicore

Reputation: 43651

You should create a defensive copy of the mutable instance:

class A {

    private final B b;

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

If B does not provide a copy constructor like this, you will need to implement defensive copying for B on your own.

If you don't do this, I can pass an instance of B to A, but also keep that instance of B to myself and mutate it later on at my own will.

Upvotes: 1

duffymo
duffymo

Reputation: 308743

Class A should not allow access to any mutable references.

Here's what your class example would look like:

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.
}

Classes B, C, and D are from a library. If you give A a mutable reference and allow the rest of the code to change the state of B or its C and D children there's nothing to be done about that. But if you construct B properly and entrust it to A, then no one else will be able to alter its state.

Upvotes: 0

Related Questions