Re: Statements before super()
On Wed, 10 Feb 2010, Mike Schilling wrote:
Tom Anderson wrote:
new SeparatedString("foo=bar", '=')
is equivalent to:
new StringPair("foo", "bar)
*/
class SeparatedString {
public SeparatedString(String str, char separator) {
// now what?
this(split(str, separator));
}
}
private String[] split(String str, char separator)
{
...
}
private SeparatedString(String[] strings)
{
super(strings[0], strings[1]);
}
I refuse to be concerned about the cost of the allocation of the String
array.
Okay. So now:
/** A string pair combining a search term, and the string resulting from
using the term as the parameter to the supplied query.
*/
class TermAndResult extends StringPair {
public KeyAndValueString(String term, PreparedStatement query) {
// and no, it's not Derby or H2
}
}
Believe me, i can keep contriving examples all week!
Propoal:
What would, I think, solve this kind of problem neatly would be to let a
constructor delegate object construction to a static factory method, hiding
the use of the factory from the caller.
What would solve the problem is allowing statements before the super call
that don't involve 'this'. This is simple, backwards compatible, and would
be *perfectly safe*!
On compatibility - it's obviously (i think) true that any code valid now
would be valid when the rules were relaxed. Could you change the language
rules without changing the VM spec? The only bit i could find in the VM
spec which bears on what a constructor can do is in 4.8.2 Structural
Constraints:
* When any instance method is invoked or when any instance variable is
accessed, the class instance that contains the instance method or
instance variable must already be initialized.
* There must never be an uninitialized class instance on the operand
stack or in a local variable when any backwards branch is taken. There
must never be an uninitialized class instance in a local variable in code
protected by an exception handler. However, an uninitialized class
instance may be on the operand stack in code protected by an exception
handler. When an exception is thrown, the contents of the operand stack
are discarded.
* Each instance initialization method (3.9), except for the instance
initialization method derived from the constructor of class Object, must
call either another instance initialization method of this or an instance
initialization method of its direct superclass super before its instance
members are accessed. However, instance fields of this that are declared
in the current class may be assigned before calling any instance
initialization method.
The most painful thing there is the ban on backward branches; that rules
out loops before the super invocation. The ban on exception handlers could
also be awkward. I don't understand the rationale behind those particular
rules, so i can't really suggest how they could be relaxed.
tom
--
william gibson said that the future has already happened, it just isn't
evenly distributed. he was talking specifically about finsbury park. --
andy