wood burning stoves 2.0*
The moose likes Java in General and the fly likes Immutable in Java - Queries in Implementation Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Immutable in Java - Queries in Implementation" Watch "Immutable in Java - Queries in Implementation" New topic
Author

Immutable in Java - Queries in Implementation

Vaibhav G Garg
Ranch Hand

Joined: Sep 23, 2011
Posts: 140
Hi All,

Below are the steps to be followed to make an Object as IMMUTABLE:

i. Don't provide any setter method for fields/properties.

ii. Mark all the fields as private.

iii. Mark all the methods as final so that methods can't be overridden.

iv. Mark the class as final so that class can't be subclassed.

Now, I have the following queries:

i. If the class is marked as final, then why do we need to mark the methods as final since anyways we can't subclass this class.

ii. If the fields are already private, then what is the use of making the methods as final since anyways we can't access the properties in subclasses.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2172
    
  47
You should also include in that list "Don't provide any method that changes the state of the object"
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4167
    
  21

Vaibhav G Garg wrote:i. If the class is marked as final, then why do we need to mark the methods as final since anyways we can't subclass this class.

It is redundant to label the class as final and its methods as final. Labeling the methods as final has no effect, since all methods in a final class are effectively final. It does't hurt though. This is from the JLS:
JLS Chap8 Sec4 wrote:A private method and all methods declared immediately within a final class (ยง8.1.1.2) behave as if they are final, since it is impossible to override them.
JLS 8.4.3.3

Note that the opposite is not true. You can't make the methods all final and not the class.


Vaibhav G Garg wrote:ii. If the fields are already private, then what is the use of making the methods as final since anyways we can't access the properties in subclasses.

If the class was not final, and so its methods were not final, a subclass could use a member variable of its own and override the getter methods to use this different variable the subclass does have access to. The subclass could then allow state change that the super class could not control. Since, at that point, not all instances of the super class are immutable then you can't assume any are.


Steve
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Steve Luke wrote:Note that the opposite is not true. You can't make the methods all final and not the class.


Well, you can. It just won't have the same effect.


a subclass could use a member variable of its own and override the getter methods to use this different variable the subclass does have access to.


Heck, it wouldn't even need a member variable. Just returning a constant, or super.getFoo() + 1 or the current time or a random value would do it.
Vaibhav G Garg
Ranch Hand

Joined: Sep 23, 2011
Posts: 140
Thanks Steve and Jeff.

I still have the following query:

1. If the variable is marked as private and final, then I assume that we can't change the value of a variable, so, why do we need to mark the method as final?
Carles Gasques
Ranch Hand

Joined: Apr 19, 2013
Posts: 199
    
    1
Hi,

My thoughts on the topic

i. If the class is marked as final, then why do we need to mark the methods as final since anyways we can't subclass this class.

I think that is not required but you get a better chance that the compiler transforms the method to native code (HotSpot).

ii. If the fields are already private, then what is the use of making the methods as final since anyways we can't access the properties in subclasses.

You still can have access to private methods through reflection.


Best regards,
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37970
    
  22
Those steps are necessary. but I can still write a class which follows all those instructions and whose state is mutable.
I shall give you a few hours to work out what additional action must be taken in order to make the class immutable.

And, by the way: please always tell us where such material comes from.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Vaibhav G Garg wrote:1. If the variable is marked as private and final, then I assume that we can't change the value of a variable, so, why do we need to mark the method as final?


If the class is final, then the method doesn't have to be final. But if neither one is final, then a subclass can override the method to return whatever it wants.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Carles Gasques wrote:
ii. If the fields are already private, then what is the use of making the methods as final since anyways we can't access the properties in subclasses.

You still can have access to private methods through reflection.


We don't even need to do that. We don't need to access the fields to violate immutability. If a subclass can exist and can override a method that reflects the object's state, then all that subclass has to do to break immutability is return a different value from its method than what the parent returns. Even though the internal state of the object may not have changed, to a user of the class, it appears that it has.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37970
    
  22
There is still another pitfall which I haven't mentioned.
Vaibhav G Garg
Ranch Hand

Joined: Sep 23, 2011
Posts: 140
Campbell Ritchie wrote:There is still another pitfall which I haven't mentioned.


Thanks Jeff and Campbell.

Hi Campbell, can you please highlight that pitfall also.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37970
    
  22
Sorry for the delay in replying. Can you see the pitfall?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37970
    
  22
Have you found the pitfall yet?
Bill Clar
Ranch Hand

Joined: Sep 21, 2006
Posts: 150

I hope it's alright if I answer.

The pitfall is the reference to the numbers array in the constructor and getNumbers(). The array is not copied, so the reference can be manipulated
from outside the scope of the Immutable class.

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37970
    
  22
Agree. You need to take a defensive copy of any mutable reference types, which includes arrays, whenever they go into your class (constructor) or come out (getXXX methods).
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Campbell Ritchie wrote:Agree. You need to take a defensive copy of any mutable reference types, which includes arrays, whenever they go into your class (constructor) or come out (getXXX methods).


So the rules in the OP should have included:

v. If any mutable fields are exposed to the outside world, their contents must be copied to a new object first, and that object, not the field, must be what's exposed.

with the corollary:

vi. If any mutable objects are accepted as arguments for establishing the object's state, their contents must be copied toa new object first, and a reference to that new object must be what's stored as the field.


Also note that both of those rules include recursive references to immutability, with the implication that any mutable objects passed in or out must be deep cloned over all their own mutable fields.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2991
    
    9
Jeff Verdegan wrote:So the rules in the OP should have included:

v. If any mutable fields are exposed to the outside world, their contents must be copied to a new object first, and that object, not the field, must be what's exposed.

I think "mutable field" is misleading here; it sounds to me like it could refer to any non-final field. I think you mean: a field which references a mutable type. Such as an array or a StringBuilder, but not a String.

There's another loophole in the rules given so far: it's not thread-safe. If the fields are not made final, then it's possible for some threads to see fields in their uninitialized values.

If you make all fields final, rule ii becomes irrelevant. Making fields private is considered a good principle for OO programming: hide your data, favor encapsulation. But it's unnecessary for making your object immutable. Provided the field is final.

If you don't want to make the fields final, well there are other ways to make the design thread-safe (effective immutability with safe publication, or force a memory barrier before every read) but they are hard to comprehend or explain. Making fields final should be considered the preferred way.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Mike Simmons wrote:
Jeff Verdegan wrote:So the rules in the OP should have included:

v. If any mutable fields are exposed to the outside world, their contents must be copied to a new object first, and that object, not the field, must be what's exposed.

I think "mutable field" is misleading here; it sounds to me like it could refer to any non-final field. I think you mean: a field which references a mutable type. Such as an array or a StringBuilder, but not a String.


Yeah, I got lazy. Thanks for clarifying.

If you make all fields final, rule ii becomes irrelevant.


As long as that rule is applied recursively to all fields that point to mutable objects as well, yes. Which it would be if it's one of our rules of immutability, and that definition of immutability is applied recursively to all fields.

Fun stuff!

I've often wished there was an immutable keyword or something in Java. I suppose it could be done with annotations. There are times when it would be nice to look at either a class or a particular instance of a class, and know (without having to dig into its source and the source of all its fields) that it will be immutable.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2991
    
    9
Jeff Verdegan wrote:I've often wished there was an immutable keyword or something in Java. I suppose it could be done with annotations. There are times when it would be nice to look at either a class or a particular instance of a class, and know (without having to dig into its source and the source of all its fields) that it will be immutable.

I think this is long overdue. There was one in JSR-305, but that's dormant. @Immutable is used as an example in JSR-308, which is supposedly coming in Java 8. But I don't know if @Immutable itself will be included, or if that's deferred to later. The Checker framework has an Immutable, but that's checkers.igj.quals.Immutable, so not quite mainstream, I'd say. You can get a JSR 305 jar file that has javax.annotation.concurrent.Immutable, which sounds relatively official, and is used by FindBugs. I'm not sure why that project is listed as dormant now.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Immutable in Java - Queries in Implementation
 
Similar Threads
How to make class immutable ?
Value Object(VO) - Immutable class
Math class immutable
Immutable classes
Immutable Class