Initialization order brain-damage

D

Dave Rush

Hi y'all,

So after spending a particularly frustrating afternoon debugging
through constructors and browsing the Java Language Specification 3.0
in some detail, I have come to the conclusion that I actually know
nothing and need to ask a question:

What is the standard order of evaluation of expressions during object
construction w/rt constructors, super-constructors, and instance
variable initializers? Specifically with the code:

class A
{
AType a1 = new AType();

A() { aDoesSomething(); }
}

class B extends A
{
AnotherType b1 = new AnotherType();

B() { bDoesSomethingElse(); }
}


B bongo = new B();

when do all of the various bits get executed? If there's a section of
the language spec that tells me this, I would really appreciate the
pointer, as well...

david rush
 
L

Lew

Dave said:
Hi y'all,

So after spending a particularly frustrating afternoon debugging
through constructors and browsing the Java Language Specification 3.0
in some detail, I have come to the conclusion that I actually know
nothing and need to ask a question:

What is the standard order of evaluation of expressions during object
construction w/rt constructors, super-constructors, and instance
variable initializers? Specifically with the code:

class A
{
AType a1 = new AType();

A() { aDoesSomething(); }
}

class B extends A
{
AnotherType b1 = new AnotherType();

B() { bDoesSomethingElse(); }
}


B bongo = new B();

when do all of the various bits get executed? If there's a section of
the language spec that tells me this, I would really appreciate the
pointer, as well...

Assuming you mean during the call to new B(),

Space for new B is allocated
superclass default constructor
new AType()
aDoesSomething() <== better not be significant or overridable or have to do
with anything other than constructing an A
new AnotherType()
bDoesSomethingElse() <== better not be significant or overridable or have to
do with anything other than constructing a B

<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.7.1>
 
S

Stefan Ram

Dave Rush said:
What is the standard order of evaluation of expressions during
object construction w/rt constructors, super-constructors, and
instance variable initializers? Specifically with the code:

instance initialization

»memory space is allocated for it with room for all the
instance variables declared in the class type and all the
instance variables declared in each superclass [...] All
the instance variables in the new object, including those
declared in superclasses, are initialized to their default
values [...] evaluate the arguments and process [explicit
or implicit] constructor invocation recursively using
these same five steps. [...] Execute the instance
initializers and instance variable initializers [...] in
the left-to-right order in which they appear textually in
the source code for the class. [...] Execute the rest of
the body of this constructor.«

JLS3, 12.5

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.5

instance initializer

»Instance initializers (§8.6) are blocks of executable
code that may be used to help initialize an instance when
it is created (§15.9).«

JLS3, 8 Classes

http://java.sun.com/docs/books/jls/third_edition/html/classes.html

instance variable initializer

»Initialization expressions for instance variables«

JLS3, 8.3.2.2 Initializers for Instance Variables

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.2.2
 
P

Patricia Shanahan

Dave said:
Hi y'all,

So after spending a particularly frustrating afternoon debugging
through constructors and browsing the Java Language Specification 3.0
in some detail, I have come to the conclusion that I actually know
nothing and need to ask a question:

What is the standard order of evaluation of expressions during object
construction w/rt constructors, super-constructors, and instance
variable initializers? Specifically with the code:

class A
{
AType a1 = new AType();

A() { aDoesSomething(); }
}

class B extends A
{
AnotherType b1 = new AnotherType();

B() { bDoesSomethingElse(); }
}


B bongo = new B();

when do all of the various bits get executed? If there's a section of
the language spec that tells me this, I would really appreciate the
pointer, as well...

The best overall description that I've found is at:

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#44670

12.5 Creation of New Class Instances

Patricia
 
S

Stefan Ram

JLS3, 12.5

Simplified and in my wording:

0 set fields to default values as they are specified by
the language

1 invoke the (implicit or constructor-called)
super-constructor and perform steps 1-3 for the superclass

2 do the explicit initializations (variable and instance
initializers) in the source-code order

3 execute the rest of the constructor
 
S

Stefan Ram

0 set fields to default values as they are specified by
the language
1 invoke the (implicit or constructor-called)
super-constructor and perform steps 1-3 for the superclass
2 do the explicit initializations (variable and instance
initializers) in the source-code order
3 execute the rest of the constructor

e.g.,

class B
{ int a = Do.print( "B0" );
{ Do.print( "B1" ); }
int b = Do.print( "B2" );
public B(){ Do.print( "B4" ); }
{ Do.print( "B3" ); }}

class A extends B
{ int c = Do.print( "A0" );
{ Do.print( "A1" ); }
int d = Do.print( "A2" );
public A(){ Do.print( "A4" ); }
{ Do.print( "A3" ); }}

public class Main
{
public static void main( final java.lang.String[] args )
{ new A(); }}

class Do
{ public static int print( final java.lang.String text )
{ java.lang.System.err.println( text ); return 1; }}

/* prints
B0
B1
B2
B3
B4
A0
A1
A2
A3
A4
*/
 
P

Patricia Shanahan

Stefan said:
Simplified and in my wording:

0 set fields to default values as they are specified by
the language

1 invoke the (implicit or constructor-called)
super-constructor and perform steps 1-3 for the superclass

2 do the explicit initializations (variable and instance
initializers) in the source-code order

3 execute the rest of the constructor

Excellent summary. Do you think it would be possible to avoid the
appearance of unbounded recursion without making it too detailed and
complicated? Something like this:

0 set fields to default values as they are specified by
the language

1 If not in new Object() constructor invoke the (implicit
or constructor-called) super-constructor and perform
steps 1-3 for the superclass

2 do the explicit initializations (variable and instance
initializers) in the source-code order

3 execute the rest of the constructor

It also does not deal with this() on the first line of a constructor,
but I can't see how to fold that in without making it too complicated.
This is obviously a trade-off between level of detail and being clearer
than the JLS description.

Patricia
 
S

Stefan Ram

Patricia Shanahan said:
If not in new Object() constructor invoke the (implicit

Thanks for the correction! I already was aware of this
inaccuracy and am accepting it for the sake of
simplification. Feel free to use and publish the list of steps
including this modification regarding the class »Object«,
while I might not add it to my own list.
 
D

Dave Rush

2 do the explicit initializations (variable and instance
initializers) in the source-code order

This is the piece of the text in 12.5 that my brain just kept blipping
over. The verbage is dreadful. Thank you so much for the help.

I should add that I think this is broken behavior! If a subclass
overrides a method used in a superclass contructor that needs an
initialized field in the subclass, you're just completely hosed. You
have to resort to copy&paste reuse or a lazy initializer via a getter
method. Leaving the desirability of accessing all instance vars
through getters aside for the moment, this leaves open a rather large
hole for non-obvious bugs in systems with high-levels of black-box
reuse as are commonly being built in Java today.

david
 
T

Tom Hawtin

Dave said:
This is the piece of the text in 12.5 that my brain just kept blipping
over. The verbage is dreadful. Thank you so much for the help.

I should add that I think this is broken behavior! If a subclass
overrides a method used in a superclass contructor that needs an
initialized field in the subclass, you're just completely hosed. You

But if you want initialiser code to access this (say, an inner class),
you would be hosed if super had not been called.

Don't call overrideable methods from constructors (unless specifically
designed otherwise).

Tom Hawtin
 
D

David Rush

Poo. It looks like the Google groups interface just ate my well-
thought-out and carefully reasoned post. This means that this one is
my grumpy migraine-influenced version...

But if you want initialiser code to access this (say, an inner class),
you would be hosed if super had not been called.

Well, potayto, potahto. Gripping hand is that there is no way to run
anything before the superclass constructor code. This is good if you
like flexibility in your reuse patterns, bad if you fear people
reusing your code in surprising ways. So basically the standard
supports incompetent programmers rather than enabling competent ones.
Don't call overrideable methods from constructors (unless specifically
designed otherwise).

Well the call of the overridable method wasn't in *my* code. It was in
a 3rd party constructor's and I had no control over that code. This
particular control had gotten good reviews on various java community
sites and has been around for more than a few years, so I expected the
code to be relatively mature. So basically your preaching "never reuse
any black-box code", which is reasonable, but terribly unfashionable
just now.

And do you really want the compiler to barf on any calls of non-final/
non-private methods in a constructor?

david
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top