In order to amke the class immutable we must restrict changing the state of the class object by any means. This means
avoiding an assignment to a variable. We can achieve this through a final modifier. To further restrict the access we can use a private access modifier.
Above do not provide any method where we modify the instance variables.
But one problem is that, what if someone creates a sub class from this immutable class? The new subclass can contain methods, which override our base
class(immutable class) method. From this class we can change the variable values.
So one approach is to make the methods final in the class or more better approach, make the immutable class itself final. So there is no overriding only.
For example, String is an immutable class and it's final.
Your Immutable class example seems to be immutable to me (even though the class isn't declared final).
Even if someone tries to extend the class, there isn't much they could do to change the immutable property of the class. I would be curious to know if someone thinks otherwise and why.
But I suppose there is much more to immutable Strings than what is shown in this particular example. You can set the String specific values and everytime you do this a new String is being created and the original String still remains in the String pool. You could have to give it some careful thought to design a class like that.
Larry Olson wrote:Your Immutable class example seems to be immutable to me (even though the class isn't declared final).
Yes, it is. Except as you say for omitting to declare it final. Consider this:
Which is clearly mutable. But so what? you might say. That's a subclass. How does it affect the immutability of the superclass? Well, consider this:
There you have an object of Immutable type (it's a subclass, but that doesn't matter). And you called a method -- getName -- which modified the state of the object. The output of the two print statements will demonstrate that by being different.
According to a Java tutorial, these conditions must be met in order for an object to be immutable:
1. Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
2. Make all fields final and private.
3. Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
4. If the instance fields include references to mutable objects, don't allow those objects to be changed:
* Don't provide methods that modify the mutable objects.
* Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.