你的例子之间的区别是操作的顺序。在你的第一个例子,与初始化块,你说,顺序是:
- 分配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