class Bird {
{
System.out.print("b1 ");
}
public Bird() {
System.out.print("b2 ");
}
}
class Raptor extends Bird {
static {
System.out.print("r1 ");
}
public Raptor() {
System.out.print("r2 ");
}
{
System.out.print("r3 ");
}
static {
System.out.print("r4 ");
}
}
class Hawk extends Raptor {
public static void main(String[] args) {
System.out.print("pre ");
new Hawk();
System.out.println("hawk ");
}
}
I'm preparing for Java OCA exam. Above code is from the book I'm studying right now. According to the answer the result should be
r1 r4 pre b1 b2 r3 r2 hawk
while I would expect it to be
pre r1 r4 b1 b2 r3 r2 hawk
taking into consideration these rules:
Could someone please show me step by step how this happens? I can understand r1
and r4
to come before everything but why pre
right after them?
答案 0 :(得分:2)
When the class Hawk
is loaded, the class Raptor
and Bird
must also be loaded because, as they are the superclass(es), they are part of the definition of Hawk
. When the class is loaded the static initializers are run. "static" really just means it is part of the class rather than instances of the class.
The next thing the JVM does is begin executing the main
method. It is static, so no instance is created yet. That is why 'pre' is printed next.
Then the main method creates an instance of Hawk
, which will invoke the constructor. Prior to entry in the constructor method the non-static intializer blocks are executed, along with field initialization (which these classes do not have any), in order in the file.
After this it prints 'hawk' and exits.
PS. When writing code I avoid initializer blocks. It is easier to read the code and understand it later when all the statements are in the constructor method. An exception is to build constant collections (ie Maps) since Java doesn't really support it otherwise (unlike Python or JavaScript syntax for literal maps/dicts/objects).
答案 1 :(得分:1)
first class Hawk
should loaded to run main method .but before Hawk get loaded super class Raptor
should get loaded .so
first Raptor
get loaded and static blocks of Raptor
run and it prints r1
and r4
答案 2 :(得分:1)
First instruction in constructor is invoking constructor of its parent class super(params).
Code in initializer block is executed after super() call .
At first class Hawk
is loaded.Since it extends Raptor
, that class is also loaded.When Raptor
is loaded, it executes static blocks in it.
Thus you get r1 r4
After that main method executes.Thus o/p becomes r1 r4 pre
.
Then Hawk
is loaded.On calling constructor of Hawk
,Raptor's
constructor is called.Raptor's
constrcutor calls Bird's
constructor.This loads the Bird
class and static block inside Bird
is executed followed by construtor.
Thus o/p becomes r1 r4 pre b1 b2
After Bird's
constructor finishes, the r3 block is executed and Raptor's
constructor finihes.
O/p becomes r1 r4 pre b1 b2 r3 r2 .
And finally last sysout is executed