aspose file tools*
The moose likes Beginning Java and the fly likes Overloading constructors with differing intializations 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 » Beginning Java
Bookmark "Overloading constructors with differing intializations" Watch "Overloading constructors with differing intializations" New topic
Author

Overloading constructors with differing intializations

Joe McCarthy
Greenhorn

Joined: Sep 28, 2005
Posts: 14
I want to be able to call a constructor with no parameters, and have default values be used for class instance variables, or call a constructor with parameters that set those variables, and then do some common stuff.

I tried two variations. In one, the parameterless constructor does the common stuff, and the multiple parameter constructor does initialization first, then calls the parameterless constructor.

This doesn't compile because the call to "this()" must be the first method called in the constructor.

In the second, the parameterized constructor does the work, and the parameterless constructor calls the parameterized constructor, passing it the default value.

"this( x )" doesn't compile because x doesn't have a value yet (since the instance has not yet been constructed when the constructor is invoked).

I have a feeling I'm missing something embarrassingly obvious, but I can't figure out how to get this work. Thanks, in advance, for any assistance!
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Does this help...?


"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer
sscce.org
Joe McCarthy
Greenhorn

Joined: Sep 28, 2005
Posts: 14
Hi Marc,

Thanks for the suggestion. Unfortunately, I want to do the initialization before calling the no-arg version (rather than after).

Joe.
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Originally posted by Joe McCarthy:
... Unfortunately, I want to do the initialization before calling the no-arg version (rather than after)...

That is unfortunate, because if you're going to call "this" in a constructor, it must be the first call. So I don't see a way to initialize using constructor arguments prior to calling the no-args constructor -- unless I'm also missing something obvious.

What specifically are you doing? There must be a way to get the desired results.
[ November 19, 2005: Message edited by: marc weber ]
Joe McCarthy
Greenhorn

Joined: Sep 28, 2005
Posts: 14
After further reflection, I realiized that I do not want one constructor to be, strictly speaking, simply a superset of the other. When I call it without any arguments, I want the class to read a configuration file; if I pass it a pair of strings (for host and name), I want to use those instead of whatever is in the file (I don't want to even read the file in that case) ... and set the private instance variables to the host & name it is passed via the constructor.

I've split off a separate "init" method ... but since I want to be able to be able to switch to a new database while the application is still running, I have overloaded that as well.

I'll copy and paste the actual "workaround" code I'm using. I'm still curious about whether there would be a more elegant solution if I didn't have the configuration file issue, but it's a lower priority issue (now).

Sorry to have taken up the bandwidth here without having thought this all through more thoroughly!

[ November 19, 2005: Message edited by: Joe McCarthy ]
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

The only thing I would caution you on is the general practice of calling instance methods from a constructor. Until the constructor finishes, you can't really be sure that you have a "complete" instance ready to go. So under certain circumstances, calling an instance method at that stage might give unexpected results.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by marc weber:
Does this help...?


I don't like it, because initializing y twice doesn't communicate very well. It also holds you from declaring y as final.

The common idiom is to call the more generic constructor with the default values in the more specific constructor. Joe had it almost right:



To me, this is more clear, as it communicates perfectly what the no-arg constructor is doing. If you want to know what value x will be initialized with, it's much more clear than in the other examples, in my opinion.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Joe McCarthy:
After further reflection, I realiized that I do not want one constructor to be, strictly speaking, simply a superset of the other. When I call it without any arguments, I want the class to read a configuration file; if I pass it a pair of strings (for host and name), I want to use those instead of whatever is in the file (I don't want to even read the file in that case) ... and set the private instance variables to the host & name it is passed via the constructor.


Reading a configuration file is too much work for a constructor, in my opinion. If I wanted to have the code in the same class, I'd make it a creation method:



But probably this still would vialote the Single Responsibility Principle - I'd probably like to decouple Foo from the logic of reading the config file, so I might extract the static method into a different class (where it might even become non-static).
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Overloading constructors with differing intializations
 
Similar Threads
a question about default constructor
Question On Comparator
Instance blocks.
local variables
newInstance()