你的例子之間的區別是操作的順序。在你的第一個例子,與初始化塊,你說,順序是:
- 分配1至
a
(在聲明)
- 輸出
a
(在初始化塊)
。 ..但在你的例子例子,它是
- 分配0(默認值)
a
(實際上在聲明)
- 輸出
a
(在初始化塊)
- 分配1至
a
(構造函數中)
理解實例初始化對我來說,關鍵是這樣的:實例初始化代碼字面上複製到構造 —所有這些,包括由編譯器默認的 —。它以源代碼順序複製,並且在構造函數中的任何內容之前(包括super
)。
下面是一個更完整的例子。考慮這個類:
class Example {
// Instance field with initializer
private int i = 5;
// Instance initialization block
{
System.out.println(this.i);
}
// constructor 1
Example() {
System.out.println(this.i * 2);
}
// constructor 2
Example(int _i) {
this.i = _i;
System.out.println(this.i * 3);
}
}
也就是說,就好像是這個已經編譯成字節碼正是:
class Example {
// Instance field
private int i;
// constructor 1
Example() {
// begin copied code
this.i = 5;
System.out.println(this.i);
// end copied code
System.out.println(i * 2);
}
// constructor 2
Example(int _i) {
// begin copied code
this.i = 5;
System.out.println(this.i);
// end copied code
this.i = _i;
System.out.println(this.i * 3);
}
}
在上述兩種情況下,Oracle的Java 8輸出完全相同的字節碼(通過使用javap -c Example
觀看編譯後):
Compiled from "Example.java"
class Example {
Example();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: aload_0
5: iconst_5
6: putfield #2 // Field i:I
9: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
12: aload_0
13: getfield #2 // Field i:I
16: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
19: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
22: aload_0
23: getfield #2 // Field i:I
26: iconst_2
27: imul
28: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
31: return
Example(int);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: aload_0
5: iconst_5
6: putfield #2 // Field i:I
9: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
12: aload_0
13: getfield #2 // Field i:I
16: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
19: aload_0
20: iload_1
21: putfield #2 // Field i:I
24: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
27: aload_0
28: getfield #2 // Field i:I
31: iconst_3
32: imul
33: invokevirtual #4 // Method java/io/PrintStream.println:(I)V
36: return
}
檢查http://stackoverflow.com/questions/19561332/in-what-order-do-static-blocks-and-initialization-blocks-execute-when-using-inhe – TheLostMind
提示:除了詢問問題。考慮一個人**真的**這樣的事情應該做的事**:學習Java語言規範,例如https://docs.oracle.com/javase/specs/jls/ se8/html/jls-8.html#jls-8.3.2我在說的是:似乎你想要走到最深處。那麼不要相信人們在這裏給你答案(太多)。學習閱讀規格(在要求其他人教你之前或之前) – GhostCat