Observe the code:
public class CodeBlockSeq {
static int k = 0;
static protected String log(Class<?> cls, String message) {
return log(cls, "static", message);
}
static protected String log(Class<?> cls, String name, String message) {
System.out.println(k++ +":"+ cls.getSimpleName() +':'+ name +':'+ message );
return message;
}
static public class Hello {
final protected String name;
private static String s0 = CodeBlockSeq.log(Hello.class,"var 0");
private String a0 = log(Hello.class,"var 0");
static {
CodeBlockSeq.log(Hello.class, "block 0");
}
private static String s1 = CodeBlockSeq.log(Hello.class,"var 1");
private String a1 = log(Hello.class, "var 1");
{
log(Hello.class, "init block 1");
}
public Hello(String name) {
this.name = name;
log(Hello.class,"Constructor\n");
}
private static String s2 = CodeBlockSeq.log(Hello.class,"var 2");
private String a2 = log(Hello.class, "var 2");
{
log(Hello.class, "init block 2");
}
static {
CodeBlockSeq.log(Hello.class, "block 2");
}
private static String s3 = CodeBlockSeq.log(Hello.class,"var 3");
private String a3 = log(Hello.class, "var 3");
{
log(Hello.class, "init block 3");
}
private static String s4 = CodeBlockSeq.log(Hello.class, "var 4");
protected String log(Class<?> cls, String message) {
return CodeBlockSeq.log(cls, "Hello-"+name, message);
}
}
static public class Bello extends Hello {
// static private Hello s0 = new Hello("jello");
private static String s0 = CodeBlockSeq.log(Bello.class,"var 0");
private String a0 = log(Bello.class, "var 0");
static {
CodeBlockSeq.log(Bello.class, "block 0");
}
private static String s1 = CodeBlockSeq.log(Bello.class,"var 1");
private String a1 = log(Bello.class, "var 1");
{
log(Bello.class, "init block 1");
}
public Bello(String name) {
super(name);
log(Bello.class, "Constructor\n");
}
private static String s2 = CodeBlockSeq.log(Bello.class,"var 2");
private String a2 = log(Bello.class, "var 2");
{
log(Bello.class, "init block 2");
}
static {
CodeBlockSeq.log(Bello.class, "block 2");
}
private static String s3 = CodeBlockSeq.log(Bello.class,"var 3");
private String a3 = log(Bello.class, "var 3");
{
log(Bello.class, "init block 3");
}
private static String s4 = CodeBlockSeq.log(Bello.class,"var 4");
public String getName() {
return this.name;
}
protected String log(Class<?> cls, String message) {
return null;
}
}
@Test
public void testIt() {
Hello x = new Bello("pollo") {
private String a1 = log(this.getClass(), "var 1");
{
log(this.getClass(), "init block 1");
}
private String a2 = log(this.getClass(), "var 2");
{
log(this.getClass(), "init block 2");
}
private String a3 = log(this.getClass(), "var 3");
{
log(this.getClass(), "init block 3");
}
protected String log(Class<?> cls, String message) {
return CodeBlockSeq.log(cls, "pollo-"+name, message);
}
};
}
}
Running the test would produce:
0:Hello:static:var 0
1:Hello:static:block 0
2:Hello:static:var 1
3:Hello:static:var 2
4:Hello:static:block 2
5:Hello:static:var 3
6:Hello:static:var 4
7:Bello:static:var 0
8:Bello:static:block 0
9:Bello:static:var 1
10:Bello:static:var 2
11:Bello:static:block 2
12:Bello:static:var 3
13:Bello:static:var 4
14:Hello:pollo-null:var 0
15:Hello:pollo-null:var 1
16:Hello:pollo-null:init block 1
17:Hello:pollo-null:var 2
18:Hello:pollo-null:init block 2
19:Hello:pollo-null:var 3
20:Hello:pollo-null:init block 3
21:Hello:pollo-pollo:Constructor
22:Bello:pollo-pollo:var 0
23:Bello:pollo-pollo:var 1
24:Bello:pollo-pollo:init block 1
25:Bello:pollo-pollo:var 2
26:Bello:pollo-pollo:init block 2
27:Bello:pollo-pollo:var 3
28:Bello:pollo-pollo:init block 3
29:Bello:pollo-pollo:Constructor
30::pollo-pollo:var 1
31::pollo-pollo:init block 1
32::pollo-pollo:var 2
33::pollo-pollo:init block 2
34::pollo-pollo:var 3
35::pollo-pollo:init block 3
Notice that they are run in this order:
- static blocks and objects of parent class
- in the order that they are declared.
- static blocks and objects of extension class
- in the order that they are declared.
- instance blocks and objects of parent class
- in the order that they are declared.
- parent constructor
- instance blocks and objects of extension class
- in the order that they are declared.
- extension class constructor
- instance blocks and objects of anonymous extension class
- in the order that they are declared.
Notice that:
// static private Hello s0 = new Hello("jello");
private static String s0 = CodeBlockSeq.log(Bello.class,"var 0");
Is a static object that is printed as the first line.
What if
replace that with:
static private Hello s0 = new Hello("jello");
// private static String s0 = CodeBlockSeq.log(Bello.class,"var 0");
So that it will print in this order
static blocks and objects of parent class
- in the order that they are declared.
Then the first static member of extension class Bello
2.1 static blocks and objects of jello's static class
- But has already run in step 1, so was not done again.
2.2 instance blocks and objects of jello instance
- in the order that they are declared.
2.3 constructor for jello instance
2.4 The rest of the static blocks and objects of extension class
- in the order that they are declared.
Just as it would have done for static String s0.
Then
- instance blocks and objects of parent class
- in the order that they are declared.
- parent constructor
- instance blocks and objects of extension class
- in the order that they are declared.
- extension class constructor
- instance blocks and objects of anonymous extension class
- in the order that they are declared.
0:Hello:static:var 0
1:Hello:static:block 0
2:Hello:static:var 1
3:Hello:static:var 2
4:Hello:static:block 2
5:Hello:static:var 3
6:Hello:static:var 4
7:Hello:Hello-null:var 0
8:Hello:Hello-null:var 1
9:Hello:Hello-null:init block 1
10:Hello:Hello-null:var 2
11:Hello:Hello-null:init block 2
12:Hello:Hello-null:var 3
13:Hello:Hello-null:init block 3
14:Hello:Hello-jello:Constructor
15:Bello:static:block 0
16:Bello:static:var 1
17:Bello:static:var 2
18:Bello:static:block 2
19:Bello:static:var 3
20:Bello:static:var 4
21:Hello:pollo-null:var 0
22:Hello:pollo-null:var 1
23:Hello:pollo-null:init block 1
24:Hello:pollo-null:var 2
25:Hello:pollo-null:init block 2
26:Hello:pollo-null:var 3
27:Hello:pollo-null:init block 3
28:Hello:pollo-pollo:Constructor
29:Bello:pollo-pollo:var 0
30:Bello:pollo-pollo:var 1
31:Bello:pollo-pollo:init block 1
32:Bello:pollo-pollo:var 2
33:Bello:pollo-pollo:init block 2
34:Bello:pollo-pollo:var 3
35:Bello:pollo-pollo:init block 3
36:Bello:pollo-pollo:Constructor
37::pollo-pollo:var 1
38::pollo-pollo:init block 1
39::pollo-pollo:var 2
40::pollo-pollo:init block 2
41::pollo-pollo:var 3
42::pollo-pollo:init block 3
Just because the static object s0 changed from String to Hello class, the java runtime does not have built-in intelligence to, make an exception for and then, relegate s0 to the back of the execution queue. It does not matter what class s0 is.