Programming is hard by Stephan Schmidt

Mutable, Immutable and Generics

Immutable objects help with avoiding bugs. Suppose I have two interfaces implementing the Immutable Interface pattern. One interface for Point and one with MutablePoint. The pattern suggests a cast to ImmutablePoint p; ((Point)p).setX( 1.0 ); get the mutable interface. This isn’t safe and can be replaced with a Generics solution.

First we have the mutable point:

public interface MutablePoint {
   public void setX(int x);
   public void setY(int y);
}

which we want to create from an Immutable object without a cast:

  Point point = point(10,10);

  MutablePoint mPoint = point.makeMutable();
  mPoint.setX(20);

The second benefit beside the missing cast is that users of the Point interface know there is a mutable interface which they can get in a defined way.

The makeMutable() method comes from a generic interface called Mutable

public interface Mutable<T> {
   public T makeMutable();
}
 

which is extended by the Point interface.

public interface Point extends Mutable<MutablePoint> {
   public int getX();
   public int getY();
}

Our Point implementation now only needs to implement MutablePoint and Point. Voila.

public class DefaultPoint implements Point, MutablePoint {
   private int x = 0;
   private int y = 0;

   public DefaultPoint(int x, int y) {
      this.x = x;
	  this.y = y;
   }

   public int getX() { return this.x; }
   public void setX(int x) { this.x = x; }
   public int getY() { return this.y; }
   public void setY(int y) { this.y = y; }

   public Point point(int x, int y) {
		return new DefaultPoint(x,y);
   }

   public MutablePoint makeMutable() {
      return this;
   }

}

A negative side effect is that people who have a reference to a Point object can get a mutable version. When the main point is to have more immutable objects. The other way round is often better, have MutablePoint and create an immutable version.

Thanks for listening.

Update: As pointed out, making an mutable object from an immutable one will break the contract, as will making an immutable one from an mutable one. You do need to copy the object to be safe. For example with a BeanCopier or a copy constructor I’ve wrote about in Beautiful Java: Reflection and the BeanCopier. Better name the method asMutable than makeMutable

public MutablePoint asMutable() {
   return new DefaultPoint(this.x, this.y);
}

If you liked this post, subscribe to my free full RSS feed.
Filed under: Java

You can share this post!
Do you want to tell others about this article? Use the social bookmark icons to submit this artice to the service of your choice. Thanks.

Get free updates by email

If you did like this article you can get free updates with your RSS reader, you can follow me on Twitter or get free update to new posts by email. Enter your email:

 
About the author: Stephan has been working as a head of development and CTO. He has experiences in different technologies since 20 years including Java, Rails and Python. Stephans main field of interest is maintainablity and productivity in software development. Want to know more? All views are only his own.

Comments

great article!

Just my 2 cents: I think that there’s a little bug. Instead of:

Point point = point(10,10);

it should be:

Point point = new DefaultPoint(10,10);

isn’t it?

stephan

Thanks :-)

point() is a factory (Fluent Interface style), see the method in DefaultPoint:


public Point point(int x, int y) {
return new DefaultPoint(x,y);
}

For more code this could be packaged into a new Object PointFactory oder PointBuilder.

Arnold

Probably it’s just a matter of taste. But the mutable state of a bean could
also be considered to be a cross cutting concern.
Another approach could therefore be to implement this concern separately
instead of as part of the bean itself.
Personally I would therefore favor the creation of a dynamically proxied Pointer
that wraps the original Pointer and throws an IllegalStateException when the settter
is called. One could implement this approach by using java.lang.reflect.Proxy
But again, maybe it’s just a matter of taste.

stephan

Yes, at least I can follow the argumentation.

With Qi4j I also would model the mutable state as a different concern.

http://www.jroller.com/rickard/entry/qi4j_status_report

Maz

Hi Stephan,

The big advantage of immutable Objects is that they are immutable and their state will not change. Otherwise you have to take care about synchronization and the java memory model.
So your suggestion will break the immutable contract.

I would have expected to get a new mutable object by changing to mutable. By the I would also expect to be able to have the possibility to get a immutable version from the mutable object.

So the makeMutable method needs a modification:
# public MutablePoint makeMutable() {
# return new DefaultPoint(x,y);
# }

Anyway, the DefaultPoint ist not really an immutable object, so it is not the best practice to use this kind of code and rely on the immutablity of the point.

stephan

@Maz: Of course, you are right. Good point.

lumpynose

Regarding Arnold’s remark about using a proxy, what about the “old fashioned” way of using inheritance? For example, see below. What I like about this way is that you can have a method that returns either a ReadOnlyPoint or a ReadWritePoint, but declares that it returns a ReadOnlyPoint;

public APIReadOnlyPoint getPoint();

The users of that method know that they’re getting a point that they cannot call the setters on, and the compiler won’t let them. No chance of exceptions being thrown.

public interface APIReadOnlyPoint {
public T getX();

public T getY();
}

public interface APIReadWritePoint extends APIReadOnlyPoint {
public void setX(T x);

public void setY(T y);
}

public class ReadOnlyPoint implements APIReadOnlyPoint {
protected T x;
protected T y;

public ReadOnlyPoint(final T x, final T y) {
this.x = x;
this.y = y;
}

@Override
public T getX() {
return x;
}

@Override
public T getY() {
return y;
}
}

public final class ReadWritePoint extends ReadOnlyPoint implements
APIReadWritePoint {
public ReadWritePoint(final T x, final T y) {
super(x, y);
}

public ReadWritePoint(final ReadOnlyPoint point) {
super(point.getX(), point.getY());
}

@Override
public void setX(final T x) {
this.x = x;
}

@Override
public void setY(final T y) {
this.y = y;
}
}

stephan

@lumpynose: How do you get a ReadOnlyPoint from an ReadWritePoint and vice versa without a cast?

Maz

@lumpynose
By definition protected members are not immutable even if the class itself does not support any setters. There could be subclasses modifying the members and your code could not rely an the immutibility.

So this raise the question of the meaning of immutable objects.
Immutable objects are under no condition modifiable. Best examples are the object representations of primitives (Integer, Boolean, etc.) and String.
JDK 1.3 could gain a huge performance gain by caching all strings and string creation and comparision was almost done in no time.

It is really nice to see what is possible with generics as Stephan demonstrated, but for this case it would rather be advisable to keep things simple and just have two different classes: One mutable and one immutable if really needed.

public interface Point
{
int getX(); int getY();
}

public class ImmutablePoint implements Point
{
private int x;
private int y;
public int getX(){return x;}
public int getY(){return y;}

public ImmutablePoint(int x1, int y1)
{
x=x1;y=y1;
}

public MutablePoint mutablePoint()
{
return new MutablePoint(x,x);
}
}

public class MutablePoint implements Point
{
protected int x;
protected int y;

public int getX(){return x;}
public int getY(){return y;}

public void setX(int x1){x=x1;}
public void setY(int y1){y=y1;}

public MutablePoint(int x1, int y1)
{
x=x1;y=y1;
}

public ImmutablePoint immutablePoint()
{
// we could here also lookup in a cache for a immutable object representing the Point and return only this instance.
return new ImmutablePoint(x,y);
}
}

lumpynose

@stephan
I’m thinking of simple value objects, so the conversions would be done via constructors that copy the object. That’s why I have the constructor ReadWritePoint(final ReadOnlyPoint point). For going the other way, from ReadWritePoint to ReadOnlyPoint, you could have a method in ReadOnlyPoint that takes as its argument a ReadWritePoint and declares that it returns a ReadOnlyPoint;

public APIReadOnlyPoint asReadOnly(APIReadWritePoint point) {
return(point);
}

lumpynose

I’m thinking that my asReadOnly doesn’t need an argument and can simply return ‘this’ and move the method to the ReadWritePoint class.

Aaron Faanes

(I’m not familiar with the pattern suggested above specifically, so pardon if I’m being redundant here :) )

Reading this post makes me think of a rather underappreciated (and apparently contentious?) class: String. String’s immutability makes life in Java unbelievably easier. If String were mutable, it is no longer an implicitly safe key-value for hashing; you would have to enforce the de facto immutability through encapsulation. On the other hand, since it is mutable, you can use it freely.

Whenever String is modified, a new String is created that represents the requested State. The original remains the same, and the newly created string is not inflexible when it comes to apparent modification.

You could use this idea as an alternative to the above pattern. Whenever you want to change the state of the object, you clone the object, passing in the new state.

Of course, this has some dangers: String concatenation is very expensive as a consequence of this, since new String’s must be created at every step. Of course, StringBuilder affords a truly mutable String that one could use, while still implementing the CharSequence interface that String does.

Because of the complementary nature of these two classes, the developer can intelligently, and easily, scale forward and backward the flexibility he wishes to present to the end-user. Furthermore, he can guarantee thread-safety (Which I think was mentioned in the comments) along with immutability of the parent (assuming this object has owners).

Something that I also appreciate, is that if you have immutable state, you can guarantee validity at all times: You’re always guaranteed an object that has proper state. This is different from mutable objects, which have to go to alot more trouble to ensure their state.

As an example, imagine setting two points on a line. After you set the first point, but before you set the second, the object is in an invalid state. The state is valid to the Line class itself, but clients of that class would not be able to sensibly work with this value. This is the true essence of thread-safety, and I think it stems from solid, proactive design.

The Date class (And, ironically, the Point class) are two examples that I (and many others) think should have been immutable, but weren’t. I imagine both were made mutable in the interests of performance and simplicity, but I think more damage was done in the long-run. This is especially true considering they could have followed the Foo/FooBuilder pattern, or the pattern discussed in the post above, instead.

All in all, favor immutability. :)

Leave a Reply