• 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:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Junilu Lacar
Sheriffs:
  • Rob Spoor
  • Liutauras Vilda
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Piet Souris
  • Tim Holloway
  • Jj Roberts
  • Stephan van Hulst
Bartenders:
  • Himai Minh
  • Carey Brown
  • Frits Walraven

How do we freeze an object while constructing an object using JavaBeans pattern.

 
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,

In Effective Java, item 2 - "Consider a builder when faced with many constructor parameters", Joshua Bloch explains the drawbacks of constructing an object that has many required and optional parameters using Telescopic pattern ( create a constructor with required parameters, create one constructor each for each optional parameter and chain them so in the end we have a constructor that has every parameter ) and the JavaBeans pattern ( construct an object using no parameter contsructor and then set the properties using setter methods ).

The author states that the drawback of using JavaBeans pattern is that an object may be in an inconsistent state partway through the construction and with javabeans pattern, we cannot make our class immutable. I have understood this much.

And then the author says that we can reduce these drawbacks by "freezing" the object when its construction is complete and not allowing it to be used until frozen. Does the author mean freeze the object by synchronizing access or something? The author also suggests later why this approach also wouldn't work. I have not understood that part too cause I have not understood how freezing works.

How do we 'freeze' an object? Following is a line from the book -
"Moreover, it can cause errors at runtime, as the compiler cannot ensure that the programmer calls the freeze method on an object before using it."

Is there a freeze method really? Which class has the freeze method? Is it deprecated now? I can't find it. I have never even come across it. The Object class does not have a freeze method, it seems.

Would you know? Please help.

Thanks,
Chan.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't have Effective Java, Second Edition (which is what you have), so I can't look up what the book says exactly, but there is certainly no special "freeze" method or built-in mechanism in Java to freeze an object.
 
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, Jesper. I thought so too, but I thought it better to confirm.

Still wondering though how we'd freeze an object using user methods. Must be synchronization he is referring to? Or can there be some other style too to freeze and unfreeze an object? External synchronization doesn't seem like a graceful way of freezing and unfreezing. Not sure if it is something that can be done correctly even with synchronization even with the simplest of classes.

Anyone who has ever come across this freezing and unfreezing of objects manually? Must be kind of unpopular?

Thanks,
Chan.
 
Sheriff
Posts: 67557
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Frankly, I've never heard of it, and never had any problems with not hearing of it.
 
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, Bear. Then I won't even try to find out.

Chan.
 
Master Rancher
Posts: 3946
51
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I suspect the "freeze" stuff was written in response to Ruby, which gained a lot of popularity in the time between the first and second edition of Effective Java. (The section on the builder pattern wasn't even in 1st edition; neither was the mention of freezing.) Anyway, Ruby has a freeze method on all objects, though its use is not very popular, for reasons which escape me. Ruby users are used to not having any compile-time enforcement of anything anyway, so Bloch's objection doesn't really apply there. But he's explaining why he thinks this is not a viable option for Java.

Here's a sketch of what it could look like, though:

I haven't analyzed it carefully, but I believe it should work under multithreading. Sure, it's tedious to write, but so are most POJOs in Java; gratuitous verbosity is a standard feature of Java. The main problem is as Bloch says; there's no way for the compiler to tell the difference between a frozen object and one that's not. It's only known at runtime.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Here's a sketch of what it could look like, though:


@Chan: And furthermore, you could write it as an interface that all "Freezable" objects implement.

BTW: <nitpick>I think it would be better to make 'frozen' volatile.</nitpick>

Winston
 
Mike Simmons
Master Rancher
Posts: 3946
51
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:BTW: <nitpick>I think it would be better to make 'frozen' volatile.</nitpick>


Yeah, I considered that too, but then I think you need to insert a read on the volatile variable in each getter as well, as a memory barrier, to prevent some out-of-order read from fetching a cached value from before the freeze. I thought "synchronized" would communicate intent more clearly, and I'm more confident in its correctness, so I went with that.
 
Mike Simmons
Master Rancher
Posts: 3946
51
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Alternately, I suppose we could make *all* the fields volatile, and drop all synchronization. That would work nicely.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Alternately, I suppose we could make *all* the fields volatile, and drop all synchronization. That would work nicely.


I think you still need to synchronize freeze(), but not anything else methinks.

Winston
 
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
This is interesting, Mike & Winston. Thank you so much for that example and explanation.

This really looks like an ungraceful and bad looking way to construct objects. First we have to do a freeze check during construction.
Granted, this window might be a small window. But consider this.
If this class were to have other methods ( non-setter methods ) too, we'd not only have to make those methods synchronized
( or use some other synchronization tool ), but also check if the object was frozen.
And if the freeze check is not done, even a synchronized method alone is broken.

Since this freeze check is not something that the compiler can enforce, it's quite a risky way to construct objects.
So I get it why we should never construct objects in this way. I think I'm getting it now.
Or was that all wrong? :-)

you could write it as an interface that all "Freezable" objects implement.


This is very interesting too. Even Joshua Bloch suggests the same style of coding for build method implementation.

Thank you,
Chan.
 
Rancher
Posts: 2759
32
Eclipse IDE Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you have AOP, or you have a factory for your objects, You could write an annotation that supports freezable. If you do have to support freezing, it seems like freezeability is a cross cutting concern. You would need a large number of classes that will need to be frozen. Also, remember that if you have a deep hierarchy of objects, you would need to freeze the whole hierarchy. If the user can do Foo.getbar().setA(...) on a frozen foo. It's not really frozen. So, the Bar class will need to be freezable, and foo will have t freeze bar. I am assuming that you are going to use this in POJOs only in which relationship between classes is always a Has a relationship and never a Uses relationship, so the entire POJO hierarchy will need to be freezable. A lot of boilerplate code in hundreds of classes in a big sized project.

So, going back to using an annotation, if you have AOP, you could annotate your classes with your custom freezable annotation. Then you can implement a Before annotation that checks if the object is frozen for setmethods. Also, for get methods, it will need to return a frozen version of the child object.

If you have your own factory, the factory can return a proxy that works similar to the annotation. It can intercept the set methods and check if the object is frozen. It can intercept get methods and return frozen version of child objects
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Chan Ag wrote:This really looks like an ungraceful and bad looking way to construct objects.


Yup; although I have used it once - to create a class similar to java.util.regex.Pattern that is cached and has a fluent interface, viz:

Regex.find("CAT").ignoreCase().in("The flat cat sat on the mat");

The reason being that a Pattern can take a fair bit of construction, so you need to be sure that it's frozen before you use it. You also don't want to cache it until it's frozen.

I guess what you need to ask yourself is: do you really need the JavaBean pattern for construction? From what I can gather it's perfectly possible to create "Bean-like" objects with a Builder - although I'm admittedly not an expert - and it saves all that faffing about associated with freezing.

Mind you, I'm biased because I far prefer immutable objects.

Winston

PS: I should add that about 2 months after I created my Regex class, I discovered that someone else had done pretty much exactly the same thing, so I was actually re-inventing the wheel. It was a fun class to write though, and I do find it very useful.
 
Jayesh A Lalwani
Rancher
Posts: 2759
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmm that's interesting. So, you used this to implement a Flyweight pattern. Yes, I can see the utility of this pattern in implementing FlyWeight.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jayesh A Lalwani wrote:Hmm that's interesting. So, you used this to implement a Flyweight pattern. Yes, I can see the utility of this pattern in implementing FlyWeight.


I didn't think of it that way, but yes, I guess so.

It just struck me that String is the wrong class to implement pattern-matching from, since it's the pattern (java.util.regex.Pattern) - and more importantly, the compiled Pattern - that's important, not the String. And since I've always been partial to fluent interfaces, it seemed like a good place to flex me "fluenting" muscles.

And it is significantly faster than the on-the-fly String methods, at least for "normal"-size Strings.

Like I say, someone beat me to it though.

Winston
 
Chan Ag
Rancher
Posts: 1090
14
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I sometimes feel I keep saying thanks every now and then and it must annoy people at times, but thanks. :-)

 
Mike Simmons
Master Rancher
Posts: 3946
51
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:Alternately, I suppose we could make *all* the fields volatile, and drop all synchronization. That would work nicely.


On second thought, I retract this. In each setter, there's a gap between checkNotFrozen() and the setting of the variable; this means that another thread could call freeze() in that gap, and the value could be observed to change after the freeze.

On the other hand, a typical model for using either freeze() or the builder pattern would be to construct the object in one and only one thread, then publish the immutable version to the other threads. As, for example, the way we typically use StringBuilder and String. We don't worry that StringBuilder is unsafe for multithreading; we only publish the immutable String version. Using this model, it is tempting to think that maybe synchronizing only the freeze() would be enough, as Winston suggests. And maybe it is. But I'm not sure. It doesn't seem to satisfy the criteria for safe publication laid out in Java Concurrency in Practice, 3.5.3:

To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:

* Initializing an object reference from a static initializer.
* Storing a reference to it into a volatile field.
* Storing a reference to it into a final field.
* Storing a reference to it into a field that is properly guarded by a (synchronized) lock.


Simply using a synchronized lock somewhere after construction does not appear to be enough. I guess we could do something like this though:

This seems to satisfy the criteria, provided other threads only access the reference returned by freeze(). Much like the builder pattern. I also removed the isFrozen() since only the constructing thread should ever see the unfrozen instance; from that thread, there should be no question whether freeze has been called yet or not.

I don't suppose this really matters, as there's still no advantage of using this technique instead of builder; both are equally onerous to write, and builder is definitely easier to use safely. The beauty of Ruby's build() method is that it's a standard method available on any object; you don't *need* to write it yourself. In Java that's not the case, so there's really no point, I think.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:This seems to satisfy the criteria, provided other threads only access the reference returned by freeze().


Another alternative (which I used in my Regex class) is to make sure that any usage method freezes the object before it runs, viz, using your example:but there are oodles of ways to do it.

Winston
 
Greenhorn
Posts: 1
Spring Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Chan,

the word "frozen" in Effective Java is used to explain the fact that final field variables can only be assigned
during constructor time.
The pattern described in this very article passes a builder object to the constructor of the nutrition and the static field variables are set within.
Afterwards the nutrition object is immutable.


 
Mike Simmons
Master Rancher
Posts: 3946
51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sven Thoden wrote:the word "frozen" in Effective Java is used to explain the fact that final field variables can only be assigned
during constructor time.


No, this is definitely not what is being said in Effective Java. We're talking about Item 2, page 13. "Freezing" is used during the discussion of the second alternative, the JavaBeans pattern - just before discussion of the third alternative, the builder pattern. Freezing is not part of the builder pattern. If final variables were used (as in builder), freezing would be unnecessary, and the compiler would be able to tell whether a given field had been set or not. Which is contrary to what Effective Java says there. You need to read it more carefully.
 
It's fun to be me, and still legal in 9 states! Wanna see my tiny ad?
Thread Boost feature
https://coderanch.com/t/674455/Thread-Boost-feature
reply
    Bookmark Topic Watch Topic
  • New Topic