From: Mike Schilling on
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
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
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
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
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.