How to implement const object in Java

The problem with const

Java does not support const objects in the manner C++ does. You can make “final” references but that only means the reference cannot be altered anymore, the object itself can. For example, I run into multiple problems in my code while getting reference to Date object that is actually member of another instance:

public class SomeClass {
  private Date date;
  public Date getDate() { return this.date; }
}

// get access to date and use it wrong:
SomeClass some=...;
Date date = some.getDate();
date.setMonth(2);

Problem here is that when writing this code I treat “date” as any primitive type and think I only got the value (the date). Then I carelessly use the same object for some other purpose modying its value. What happens is that I end up changing the member of SomeClass, which I did not intend. This in turn causes really hard-to-find bugs later in the code. In C++, I would just make getDate() to return const Date object, so any attempt to modify it would be caught by the compiler before even running the code. Alternative solution is to always clone the returning Date, which I was doing first, but this creates additional overhead for simple getters that I just don’t like.

The solution

To create a const object in Java is possible by creating a const interface that includes only the const methods (that do not modify the object) and have the object implement that interface. Then you modify all getters to return this const interface instead of the actual object reference.

public interface DateConst {
  int getMonth();
}

public class Date implements DateConst {
  @Override
  public int getMonth() {
    // code...
  }
}

This way, you do not need to split the class implementation, but only declare all const methods in this interface. Class implementation remains the same except for some @Override declarations that Eclipse adds for you anyway. In your code, use the const version of your class for any purpose that does not require modifying it. Any attempt to call non-const method on the interface leads to compiler error.

For the case that you need to create non-const clone for your const object, you should include clone() in the const interface and have it return a non-const copy.

Note that this method of course only works for your own classes and not for final classes that you do not have access to.

  

Comments are closed.