物件建構函式
Java 中的所有建構函式都必須呼叫 Object
建構函式。這是通過呼叫 super()
完成的。這必須是建構函式中的第一行。這樣做的原因是,在執行任何其他初始化之前,實際上可以在堆上建立物件。
如果你沒有在建構函式中指定對 super()
的呼叫,編譯器會為你輸入。
所以這三個例子在功能上是相同的
顯式呼叫 super()
建構函式
public class MyClass {
public MyClass() {
super();
}
}
隱式呼叫 super()
建構函式
public class MyClass {
public MyClass() {
// empty
}
}
使用隱式建構函式
public class MyClass {
}
那麼 Constructor-Chaining 呢?
可以將其他建構函式作為建構函式的第一條指令呼叫。由於對超級建構函式的顯式呼叫和對另一個建構函式的呼叫都必須是第一個指令,因此它們是互斥的。
public class MyClass {
public MyClass(int size) {
doSomethingWith(size);
}
public MyClass(Collection<?> initialValues) {
this(initialValues.size());
addInitialValues(initialValues);
}
}
呼叫 new MyClass(Arrays.asList("a", "b", "c"))
將使用 List-argument 呼叫第二個建構函式,List-argument 將依次委託給第一個建構函式(它將隱式委託給 super()
),然後使用列表的第二個大小呼叫 addInitialValues(int size)
。這用於減少程式碼重複,其中多個建構函式需要執行相同的工作。
如何呼叫特定的建構函式?
鑑於上面的例子,可以呼叫 new MyClass("argument")
或 new MyClass("argument", 0)
。換句話說,就像方法過載一樣 ,你只需使用所選建構函式所必需的引數呼叫建構函式。
Object 類建構函式會發生什麼?
沒有比在具有預設空建構函式的子類中發生的更多(減去對 super()
的呼叫)。
可以顯式定義預設的空建構函式,但如果沒有,只要沒有定義其他建構函式,編譯器就會將它放入其中。
然後如何從 Object 中的建構函式建立一個 Object?
物件的實際建立歸結為 JVM。Java 中的每個建構函式都顯示為一個名為 <init>
的特殊方法,它負責例項初始化。這個 <init>
方法由編譯器提供,因為 <init>
不是 Java 中的有效識別符號,所以它不能直接在該語言中使用。
JVM 如何呼叫此
<init>
方法?
JVM 將使用 invokespecial
指令呼叫 <init>
方法,並且只能在未初始化的類例項上呼叫。
有關更多資訊,請檢視 JVM 規範和 Java 語言規範:
- 特殊方法(JVM) - JVMS - 2.9
- 建構函式 - JLS - 8.8