This is because at compile time, the compiler moves every initialization you have done at the place of declaration to every constructor of your class. So the constructor of UCMService
class is effectively compiled to:
public UCMService(String service){
super(); // First compiler adds a super() to chain to super class constructor
dataMap = new DataMap(); // Compiler moves the initialization here (right after `super()`)
System.out.println("2222");
this.service = service;
}
So, clearly DataMap()
constructor is executed before the print
statement of UCMService
class. Similarly, if you have any more constructor in your UCMService
class, the initialization will be moved to all of them.
Let's see the byte code of a simple class:
class Demo {
private String str = "rohit";
Demo() {
System.out.println("Hello");
}
}
compile this class, and execute the command - javap -c Demo
. You will see the following byte code of constructor:
Demo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2 // String rohit
7: putfield #3 // Field str:Ljava/lang/String;
10: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
13: ldc #5 // String Hello
15: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
18: return
You can see the putfield
instruction at line 7, initializes field str
to "rohit"
, which is before the print
statement (instruction at line 15
)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…