• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Creating Immutable Classes - object reference leaks, subclass issues.

 
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

I'm trying to understand how to create immutable classes. I referred to the page --> http://javarevisited.blogspot.in/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html and it states there are four steps to do so.

1. State of immutable object can not be modified after construction, any modification should result in new immutable object.
2. All fields of Immutable class should be final.
3. Object must be properly constructed i.e. object reference must not leak during construction process.
4. Object should be final in order to restrict sub-class for altering immutability of parent class.

I have understood points 1 and 2. However I could not understand points 3 and 4. How can object reference leak during construction process?

And about point 4, if we make a class final we cannot subclass it. But if we do not make it final, how can a subclass affect the immutability.

Here is an example.





I have not made EmployeeImmutable class final. So now how subclasses can affect the immutability of this class? Sure, I can have a subclass constructor but even then can I change the value of a final variable? I suppose not or can I? And what is meant by reference leaks in the process of construction?

Could you please help me understand the underlying concepts here.

Thanks,
Chan.




 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
EDIT



are private variables as follows.


 
Rancher
Posts: 1044
6
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks so much, Ivan. I get it now.

Thank you..
Chan.
 
Ivan Jozsef Balazs
Rancher
Posts: 1044
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome.
 
Master Rancher
Posts: 5153
83
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chan Ag wrote:1. State of immutable object can not be modified after construction, any modification should result in new immutable object.
2. All fields of Immutable class should be final.
3. Object must be properly constructed i.e. object reference must not leak during construction process.
4. Object should be final in order to restrict sub-class for altering immutability of parent class.

I have understood points 1 and 2. However I could not understand points 3 and 4. How can object reference leak during construction process?


Basically, if you call any method during construction, and you pass "this" as a parameter to the method, that method may access your "immutable" data before it's actually been set - making it not immutable. Here's an example:

Running this gives:

even though there is only one Foo object created, and num is final. How does it change?

The class Foo would seem to be immutable. However, because it's calling foreignMethod(), and passing a "this" reference to it, it's opening a door to mutable behavior. Because foreignMethod() can observe the num variable in its uninitialized state.

One simple apparent workaround would be to only allow foreignMethod() to be called after num has been initialized. Often this works - however, in a multi-threaded application, it's actually still possible for other threads to observe the uninitialized value in some circumstances. Which is completely counterintuitive, but nonetheless true. Skipping over a lengthy discussion of threading issues, I'll just say that an "immutable" object is not truly immutable until its constructor has completed. Methods like foreignMethod() should be called only after the constructor completes.

There's another loophole, if foreignMethod() is not in another class, but in this class. That means you don't need to pass a "this" reference - the method already has access to it. That shouldn't be a problem as long as you, the author of the methods in this class, don't try to access the value of that variable num before it's been set. However, if foreignMethod() is overridden in a subclass, that can open up the loophole again - the value of num can be observed as mutable:

This serves as another example of why an immutable class should be final. So you don't override it with something that breaks the immutability. Note that the Boo.myMethod() code is not even malicious - it's just printing out a value. But because myMethod() is called within the constructor, it can inadvertently see something it shouldn't - namely, the uninitialized value of num.

There may be some times when you find you want or need to break rule 4 above. If so, remember another rule: never call an overrideable method from a constructor. It can lead to weird, unexpected behavior in subclasses.
 
Bartender
Posts: 11497
19
Android Google Web Toolkit Mac Eclipse IDE Ubuntu Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would also recommend going through http://www.javaranch.com/journal/2003/04/immutable.htm
 
Mike Simmons
Master Rancher
Posts: 5153
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Maneesh Godbole wrote:I would also recommend going through http://www.javaranch.com/journal/2003/04/immutable.htm


Unfortunately, that's a bit out of date now though. It was written back before the revisions to the Java memory model, and so it does not cover the importance of making fields final for true thread-safe immutability. (Or of more complicated alternatives that omit final but use other techniques to achieve thread-safety.) Nowadays, these points are important and should not be skipped over.
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Mike.

I have been waiting to view this post along with the code examples. I had connectivity issues this morning and hence I could view this post only via my cell phone. I wasn't able to login or view the complete code examples.

Now that I've gone through the examples along with the explanation, I think I have understood all that I planned to find out on the subject. Thanks so much for that. I greatly appreciate it. I'm sure I wouldn't have found such examples and explanation anywhere else.

Later on when I'm at least at a good stage in understanding threads and concurrency, I will try to find out more on how not very nicely programmed multi threaded applications might have reference leaks in construction/initialization process. And it might serve in the best of my interest to not have a method call ( as long as I can avoid it ) in the constructor/init blocks for the reasons you mentioned.

Thanks,
Chan.
 
Ranch Hand
Posts: 33
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chan Ag wrote:Thanks so much, Ivan. I get it now.

Thank you..
Chan.



I still did not get how subclass the naughtyEmployee has affected the immutability of its superclass?
 
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vivek Raj wrote:

Chan Ag wrote:Thanks so much, Ivan. I get it now.



I still did not get how subclass the naughtyEmployee has affected the immutability of its superclass?




I think you forgot that immutable objects will be used. It is not just immutability for immutability sake. Code depends on them to operate correctly. And that includes security -- imagine a parameter changing to a high secure resource *after* the instance passed the password check.

Yes, instances of the superclass is technically still immutable. However, instances of the subclass passes the IS-A test for the superclass. So, instances of the subclass are instances that IS-A superclass, can be used like the superclass, but is mutable. This will break code that depends on the immutability.

Henry
 
Vivek Raj
Ranch Hand
Posts: 33
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Henry Wong wrote:

Vivek Raj wrote:

Chan Ag wrote:Thanks so much, Ivan. I get it now.



I still did not get how subclass the naughtyEmployee has affected the immutability of its superclass?




I think you forgot that immutable objects will be used. It is not just immutability for immutability sake. Code depends on them to operate correctly. And that includes security -- imagine a parameter changing to a high secure resource *after* the instance passed the password check.

Yes, instances of the superclass is technically still immutable. However, instances of the subclass passes the IS-A test for the superclass. So, instances of the subclass are instances that IS-A superclass, can be used like the superclass, but is mutable. This will break code that depends on the immutability.

Henry



Thank you Henry.. I got the point now.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic