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!
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 ]
Joined: Sep 28, 2005
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 ]
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.
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
Joined: Jul 11, 2001
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).