From: Mike Schilling on 10 Feb 2010 19:16 Suppose the call to "super()" needn't be the first line of a constructor. Discuss the effect and/or legality of the following code: class MyClass extends YourClass { public MyClass(int i) { if ( i > 0) { super(i); } } ...
From: rossum on 10 Feb 2010 19:59 On Wed, 10 Feb 2010 18:46:05 -0500, Lew <noone(a)lewscanon.com> wrote: >rossum wrote: >> Static initialisation code in the derived class is run before super() >> in the constructor. >> >> public class Main { >> >> public static void main(String[] args) { >> >> Derived dd = new Derived(); >> >> System.out.println("Done."); >> } // end main() >> >> } // end class Main >> >> >> class Base { >> >> public Base() { >> System.out.println("Base constructor."); >> } >> >> } // end class Base >> >> >> class Derived extends Base { >> >> static { System.out.println("Derived static code."); } >> >> { System.out.println("Derived initialisation code."); } >> >> public Derived() { >> super(); >> System.out.println("Derived constructor."); >> } >> } // end class Derived >> >> **** Output **** >> >> run: >> Derived static code. >> Base constructor. >> Derived code. > >Since I don't see that string in your example, I'm guessing you meant to put > Derived initialisation code. Whoops. I changed the code and then forgot to re-run it. Thanks for the catch. I c&p'd the previous run. > >The 'println()' call for which is actually part of the constructor, btw. > >> Derived constructor. >> Done. > >I don't see "Done." in your example code either. Look in main(). rossum
From: Eric Sosman on 10 Feb 2010 21:29 On 2/10/2010 7:16 PM, Mike Schilling wrote: > Suppose the call to "super()" needn't be the first line of a constructor. > Discuss the effect and/or legality of the following code: > > class MyClass extends YourClass > { > public MyClass(int i) > { > if ( i> 0) > { > super(i); > } > } > ... Illegal[*]: It is possible to construct a MyClass instance that has not constructed its YourClass aspect. [*] Well, we're already in fairy-land. But if we're to retain any sanity, even fairy-land must abide by sane rules. A fairy-land compiler could detect the failure to call super() (or the possibility of calling it more than once) with logic similar to that which real compilers use to detect the use of "possibly uninitialized" variables. As with the latter, some situations like class OurClass extends YourClass { MyClass(String thing) { switch (thing.length() % 2) { case 0: super(42); break; case 1: super(-3); break; } } } .... would be falsely diagnosed as "might not call super()." (Because javac knows that String's length() method returns an int, but does not know that the int is non-negative.) -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: Lew on 10 Feb 2010 21:34 Lew wrote: >> I don't see "Done." in your example code either. rossum wrote: > Look in main(). (smacks self in forehead) Ok. -- Lew
From: Mike Schilling on 11 Feb 2010 02:34
Eric Sosman wrote: > On 2/10/2010 7:16 PM, Mike Schilling wrote: >> Suppose the call to "super()" needn't be the first line of a >> constructor. Discuss the effect and/or legality of the following >> code: class MyClass extends YourClass >> { >> public MyClass(int i) >> { >> if ( i> 0) >> { >> super(i); >> } >> } >> ... > > Illegal[*]: It is possible to construct a MyClass instance > that has not constructed its YourClass aspect. > > [*] Well, we're already in fairy-land. But if we're to retain > any sanity, even fairy-land must abide by sane rules. > > A fairy-land compiler could detect the failure to call super() > (or the possibility of calling it more than once) with logic similar > to that which real compilers use to detect the use of "possibly > uninitialized" variables. Now that you mention it, it's almost exactly the same logic used to determine that final fields are initialized exactly once. The only difference is that it would also need to detect that instance fields and methods are accessed only after that's done. |