aspose file tools*
The moose likes Java in General and the fly likes An immutable class using a public no-args constructor Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "An immutable class using a public no-args constructor" Watch "An immutable class using a public no-args constructor" New topic
Author

An immutable class using a public no-args constructor

Dean Pullen
Ranch Hand

Joined: May 30, 2003
Posts: 58
Hi all,

I'm trying to implement an immutable class, and am using the static builder pattern as defined in Effective Java.

i.e. http://my.safaribooksonline.com/book/programming/java/9780137150021/creating-and-destroying-objects/ch02lev1sec2

This is a usual pattern I follow. However, I'm constrained by a third party system that requires an instance of the object to be initialised via a no-args public constructor.
It will then be 'properly' initialised by a (non-static) builder at the appropriate place.

What do people think of allowing this? It seems dirty but can't quite put my finger on how dirty!

Cheers,

Dean

Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 13884
    
  10

The builder pattern is good. If there's no way around having a public no-args constructor for that third-party system, then at least describe in the Javadoc documentation for that constructor why it's there, that it's only purpose is to be used by the third-party system, and that developers should not use it directly.

You could also invent a solution where you let the third-party system not initialize your immutable object itself, but another intermediary object, and then you create your immutable object from that when the third-party system has done its job. That would however make your software more complex, so you'd have to decide if it's worth the trouble, and depending on the details of how everything works it might not even be possible.
drac yang
Ranch Hand

Joined: Apr 19, 2013
Posts: 60
if the immutable class is being implemented, i.e. hasn't been implemented yet, why does the third party system have already decided to construct it according to its own way, not according to your supplied instantiating way. it's supposed to use your class by its existing layout, i think it's a design issue.


science belief, great bioscience!
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2065
    
  22

This is common for frameworks that use reflection to initialize objects. They expect the object to have a non-args constructor, and have setter methods for the properties. The framework reads a configuration file that describes which class to instantiate and which properties to set. A very common example is java.util.logging. For the most part Logger should be immutable, but it's not. You should use the static builder to get a logger, and then use it to log. The static builder reads the logging properties and initializes the logger object. Most applications don't change the logging properties at runtime. However, the reason logger is not made immutable is because the static builder itself needs setter methods

The way I approach a problem like this is by having an immutable interface. For the most part, you want immutability because you want to delineate the code:- This factory module is responsible for initializing the object. All these other modules use the object but don't modify it. So, what I do is introduce an interface with only getter methods. All the modules that use the object are coded to the immutable interface. The actual implementation itself is mutable. The factory itself knows the concrete class and knows knows that the concrete class is mutable, and it takes advantage of mutability of the object to initialize it.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7081
    
  16

Jayesh A Lalwani wrote:For the most part Logger should be immutable, but it's not. You should use the static builder to get a logger, and then use it to log. The static builder reads the logging properties and initializes the logger object. Most applications don't change the logging properties at runtime. However, the reason logger is not made immutable is because the static builder itself needs setter methods.

Surely that doesn't stop the Logger class itself from being immutable?

I use Builders quite a lot when I've got complex objects, but it doesn't stop the object itself from being immutable after I've run build().

But I'm not familiar with Logger, so I may be missing something.

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Artlicles by Winston can be found here
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2065
    
  22

java.util.logging.Logger is mutable. The API allows the application to change logging levels and add and remove handlers at run time, although it really shouldn't. IMO, it should have been an immutable interface rather than an object.
Dean Pullen
Ranch Hand

Joined: May 30, 2003
Posts: 58
Cheers for the feedback everyone
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: An immutable class using a public no-args constructor
 
Similar Threads
A setter that can only be called by framework
Factory pattern question
how to extend a static builder
thread-safe java beans
Are public nested classes a good practice?