Is the above class written Immutable?
I have read that class or all its methods must be marked as final in order to achieve immutability but the above sample code written doesn't not force me to use "final" as per my opinion.
I am a bit confused regarding using "final" in order to write immutable classes in Java.
Any help will be highly appreciated.
By making a class final, you do not allow anyone to extend the class. When you allow your class to be extended by a sub-class, whenever you instantiate the sub-class, the super class constructor also gets invoked and the class is initialized.
It's immutable as it stands. But it doesn't force subclasses to be immutable. At the moment a subclass could add other fields and make them mutable. So if you want all Immutable objects to be definitely immutable, then you need to make the class final to prevent subclassing.
Edit: that doesn't mean it isn't good practice to mark methods final, but it doesn't generally affect immutability.
Joined: Feb 03, 2010
But even if our super class constructor gets invoked how does it change my immutable class to mutable or in other words how does it affect the immutablity of my class.
Joined: Feb 03, 2010
As you said that "a subclass could add other fields and make them mutable" how does it possible? Could you please give me an example
Also you said that "it doesn't force subclasses to be immutable" i am only concerned about my class to be immutable i don't bother about other classes
In above mentioned code, I have extended Immutable class and in Test class's main method - i have called getI() method which returns me 5.
Now I change ChildImmutable class to overridde getI() method
Now output of invoking getI() on ChildImmutable class will give me result as 4 (not 5 although Immutable object was created with instance variable 'i' value as 5 ).
So effectively purpose of Immutability has vanished.
So, base line is to
a. make class as 'final' so that it is not extended so such situation as described above does not arises
b. if due to any constraints, class cannot be defined as final then atleast make all its method as final. Marking method as final ensures that no child can change behaviour of that method.
So mark your getI() method as final.
Hope this help you
Oracle certified Java 8 Programmer I (1Z0-808), Oracle Java Web Service Developer (1z0-897), Oracle certified Java 7 Programmer, SCJA 1.0, SCJP 5.0, SCWCD 5.0, Oracle SQL Fundamentals I, CIW Certified Ecommerce specialist
For immutability it's necessary to mark all member fields final, even if they are initialized in the constructor and no methods are provided which change the value. In your Immutable class above, the value of i may look unchangeable, but it isn't. It actually changes from 0 to some other value during construction. It may seem like it's impossible for anyone to see the value of 0 since the variable has been assigned during construction - but it turns out that if you're ever writing a multi-threaded program, different threads may see things outside the sequence you expect. In particular, another thread may be able to read the value of 0 before the constructor has really completed. This is very counterintuitive, but that's true for many things about threads. They're hard to understand. But the short answer is, if you want a class to be immutable, its fields must be final, even if no mutator methods are provided.
(That's in addition to other rules for making a class immutable, like make the class itself final, and all the member fields must be immutable types as well.)
Abhay Agarwal wrote: . . . I think I need to increase my typing speed
It's usually Rob Spoor who gets an answer in quickly like that
Joined: Oct 13, 2005
Mike Simmons wrote: . . . all the member fields must be immutable types as well.)
Can't you use mutable fields if there is no reference to them held elsewhere? So any references to those fields should be defensive copies, and defensive copies should be used in the constructor. And once they are in the immutable class, no attempt is ever made to change their state.
Joined: Mar 05, 2008
That's true, there are ways to violate those rules and still get immutable behavior. It's also possible to omit final from some fields, if they are lazily initialized for example. However it requires more work and understanding of how thread safety works. It's hard to make general statements about what is and isn't safe.
If all your fields are final, and all field types are primitive or immutable, and the class itself is final, then the class is definitely immutable.
If any of those rules are violated, then the resulting class may still be immutable, but probably isn't.