• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Overloading constructors with differing intializations

 
Joe McCarthy
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does this help...?
 
Joe McCarthy
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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).
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic