aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes order when constructing Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "order when constructing" Watch "order when constructing" New topic
Author

order when constructing

Rodge Thomas
Ranch Hand

Joined: Jul 25, 2002
Posts: 38
class G {
String s1 = "G.s1";
void printS1(){System.out.print("G.printS1," + s1);}
G() { printS1();}
}
class H extends G {
String s1 = "H.s1";
void printS1(){System.out.print("H.printS1," + s1);}
public static void main(String[] args) {
H h = new H();
}
}

What is the result of attempting to compile and run the above program?
a. Prints: G.printS1,G.s1
b. Prints: G.printS1,H.s1
c. Prints: G.printS1,null
d. Prints: H.printS1,G.s1
e. Prints: H.printS1,H.s1
f. Prints: H.printS1,null
g. Runtime Exception
h. Compiler Error
i. None of the Above
ANSWER: F
EXPLANATION:
Prints: H.printS1,null The default constructor of H calls the constructor of G. The constructor of G calls the overloaded method printS1 causing the invocation of H.printS1. The instance variable H.s1 hides G.s1. Although G.s1 has already been initialized, the initialization of the instance variables of H won't begin until the initialization and construction of G is complete.
-----
how can s1 in H already be initialized to null when its value is used? I assumed AFTER the G construction process is finished that H initializes its instance member variables to default values.
thank you.


SCJP, SCWCD
Ron Newman
Ranch Hand

Joined: Jun 06, 2002
Posts: 1056
All class and instance variables start life as null (or 0) until they get their real initial values.
This example is good mainly for illustrating something that you should not do: calling a non-final, non-private instance method from a constructor. If the method is overridden in a subclass, as it is here, the subclass method will see an incompletely constructed "this" object.
I personally think the compiler should issue a warning when it sees such a method call, but it doesn't.


Ron Newman - SCJP 1.2 (100%, 7 August 2002)
Dan Chisholm
Ranch Hand

Joined: Jul 02, 2002
Posts: 1865
The Java Language Specification, Section 12.5, Creation of New Class Instances states the following.

Whenever a new class instance is created, 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 of the class type, including all the instance variables that may be hidden (�8.3). If there is not sufficient space available to allocate memory for the object, then creation of the class instance completes abruptly with an OutOfMemoryError. Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values (�4.5.5).


Dan Chisholm<br />SCJP 1.4<br /> <br /><a href="http://www.danchisholm.net/" target="_blank" rel="nofollow">Try my mock exam.</a>
Rodge Thomas
Ranch Hand

Joined: Jul 25, 2002
Posts: 38
Please correct me if I am wrong on the following:
if H extends G, and you instantiate H the following takes place in this order:
(1) set static variables of G to default values
(2) execute static initializations/blocks of G
(3) set static variables of H to default values
(4) execute static initializations/blocks of H
(5) go to very beginning of constructor G and set instance variables to defaults
(6) execute instance initializations/blocks of G
(7) execute constructor code of G
(8) go to very beginning of constructor H and set instance variables to defaults
(9) execute instance initializations/blocks of H
(10) execute constructor code of H
*so, step 8 which sets s1 in H to 'null' has not taken place when printS1() is called from the G constructor at step 7.
My point is that the instance of subclass H does not exist at the point in time when the super class constructor is invoked. This is demonstrated below in a question from the Dan Chisholm exam, included is his explanation:
class Q {
int i = 1;
{System.out.print("1");}
static {System.out.print("2");}
Q() {System.out.print("3");}
Q(int x) {System.out.print("4");}
}
class R extends Q {
int j = 2;
{System.out.print("5");}
static {System.out.print("6");}
R() {super(j);System.out.print("7");}
}
class S {
public static void main(String[] args) {
new R();
}
}

" Compiler Error
The constructor of R has an explicit call to the super class constructor that includes an instance variable as a parameter. A compiler error is generated since the instance of class R does not exist at the point in time when the super class constructor is invoked. "
any replies to clear this up will be very much appreciated.
[ August 20, 2002: Message edited by: Rodge Thomas ]
[ August 20, 2002: Message edited by: Rodge Thomas ]
Dan Chisholm
Ranch Hand

Joined: Jul 02, 2002
Posts: 1865
Rodge,
Your ten step process for initialization is close to being correct, but it isn't exactly. The Java Language Specification, Section 12.5, Creation of New Class Instances provides a good example of the process.

In the example:
class Point {
int x, y;
Point() { x = 1; y = 1; }
}
class ColoredPoint extends Point {
int color = 0xFF00FF;
}
class Test {
public static void main(String[] args) {
ColoredPoint cp = new ColoredPoint();
System.out.println(cp.color);
}
}
a new instance of ColoredPoint is created. First, space is allocated for the new ColoredPoint, to hold the fields x, y, and color. All these fields are then initialized to their default values (in this case, 0 for each field). Next, the ColoredPoint constructor with no arguments is first invoked. Since ColoredPoint declares no constructors, a default constructor of the form:
ColoredPoint() { super(); }
is provided for it automatically by the Java compiler.
This constructor then invokes the Point constructor with no arguments. The Point constructor does not begin with an invocation of a constructor, so the compiler provides an implicit invocation of its superclass constructor of no arguments, as though it had been written:

Point() { super(); x = 1; y = 1; }
Therefore, the constructor for Object which takes no arguments is invoked.
The class Object has no superclass, so the recursion terminates here. Next, any instance initializers, instance variable initializers of Object are invoked. Next, the body of the constructor of Object that takes no arguments is executed. No such constructor is declared in Object, so the compiler supplies a default one, which in this special case is:

Object() { }
This constructor executes without effect and returns.
Next, all initializers for the instance variables of class Point are executed. As it happens, the declarations of x and y do not provide any initialization expressions, so no action is required for this step of the example. Then the body of the Point constructor is executed, setting x to 1 and y to 1.
Next, the initializers for the instance variables of class ColoredPoint are executed. This step assigns the value 0xFF00FF to color. Finally, the rest of the body of the ColoredPoint constructor is executed (the part after the invocation of super); there happen to be no statements in the rest of the body, so no further action is required and initialization is complete.
Dan Chisholm
Ranch Hand

Joined: Jul 02, 2002
Posts: 1865

The constructor of R has an explicit call to the super class constructor that includes an instance variable as a parameter. A compiler error is generated since the instance of class R does not exist at the point in time when the super class constructor is invoked.

Rather than say that the instance does not exist I should have said that it has not yet been fully initialized. In the next version of the exam I'll use the following remark in place of the old one quoted above.

The constructor of R has an explicit call to the super class constructor that includes an instance variable as a parameter. A compiler error is generated since the instance of class R has not yet been fully initialized at the point in time when the super class constructor is invoked. The instance variable R.j still contains the default value of zero rather than the assigned value of 2.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: order when constructing