java類初始化的順序
先從最簡單的說起,我們一般是這樣理解的:
先初始化靜態 成員/塊 然後是構造程式碼塊,最後是建構函式 看一個例子
這是兩個類ShunXu 和 Other
public class ShunXu {
public ShunXu() {
System.out.println("建構函式");
}
public static Other other = new Other();
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
public static void main(String[] args) {
ShunXu shunXu = new ShunXu();
}
}
public class Other {
{
System.out.println("我是另一個類的構造程式碼快");
}
static {
System.out.println("我是另一個類的靜態塊");
}
}
首先明確一點,靜態程式碼塊和靜態成員變數是沒有先後之分,完全按照程式碼的順序執行
執行主函式,首先會裝載ShunXu->構造靜態成員變數other(other中先執行靜態塊,後執行構造程式碼塊)->執行靜態塊->構造程式碼塊->建構函式
因此,輸出結果就是
我是另一個類的靜態塊
我是另一個類的構造程式碼快
靜態塊
構造程式碼塊
建構函式
接下來看一個有些奇怪的例子
現在先不管Other,只關注ShunXu
public class ShunXu {
public ShunXu() {
System.out.println("建構函式");
}
static ShunXu shunXu = new ShunXu();
static ShunXu shunXu2 = new ShunXu();
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
public static void main(String[] args) {
}
}
我們在ShunXu內部建立了兩個靜態ShunXu物件
主函式本身什麼也不做,先看看輸出結果
構造程式碼塊
建構函式
構造程式碼塊
建構函式
靜態塊
是不是很神奇,靜態塊竟然最後執行
其實原因不難分析,可以看出建立兩個物件分別呼叫了兩次構造程式碼塊和建構函式,說明構造靜態物件的時候並沒有執行靜態塊,也就是說,靜態塊是由最外層的類來執行的。既然靜態塊寫在了靜態成員變數和後面,那麼它當然就得等靜態成員生成完再執行了
如果將靜態塊放在最前面
public class ShunXu {
public ShunXu() {
System.out.println("建構函式");
}
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
static ShunXu shunXu1 = new ShunXu();
static ShunXu shunXu2 = new ShunXu();
public static void main(String[] args) {
}
}
那麼輸出就是
靜態塊
構造程式碼塊
建構函式
構造程式碼塊
建構函式
這驗證我之前的說法:
靜態程式碼塊和靜態成員變數是沒有先後之分,完全按照程式碼的順序執行
那如果我們在主函式中再建立一個ShunXu物件呢
public class ShunXu {
public ShunXu() {
System.out.println("建構函式");
}
static ShunXu shunXu1 = new ShunXu();
static ShunXu shunXu2 = new ShunXu();
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
public static void main(String[] args) {
ShunXu xu = new ShunXu();
}
}
輸出為:
構造程式碼塊
建構函式
構造程式碼塊
建構函式
靜態塊
構造程式碼塊
建構函式
可以看出,這其實並沒有違背先靜態後非靜態的說法
剩下的就是關於父類的說明了
class Parent{
public Parent(){
System.out.println("父類構造方法");
}
static {
System.out.println("父類靜態塊");
}
}
public class ShunXu extends Parent{
public ShunXu() {
System.out.println("建構函式");
}
static ShunXu shunXu1 = new ShunXu();
static ShunXu shunXu2 = new ShunXu();
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
public static void main(String[] args) {
ShunXu xu = new ShunXu();
}
}
輸出結果為
1父類靜態塊
2父類構造方法
3構造程式碼塊
4建構函式
5父類構造方法
6構造程式碼塊
7建構函式
8靜態塊
9父類構造方法
10構造程式碼塊
11建構函式
輸出有些多,我們把它們給分割 1 - 7是兩個靜態成員的構造過程,先對載入其父類 然後呼叫父類構造方法 然後自身構造 8 - 11就是一個正常的物件的構造過程
說複雜的確有點,想通了其實問題就不大
相關文章
- Java 類初始化順序Java
- Java類初始化順序Java
- Java類(繼承)初始化順序Java繼承
- Java子類和父類的初始化執行順序Java
- Java初始化順序Java
- 淺談Java類中的變數初始化順序Java變數
- JAVA物件的初始化順序Java物件
- Java中class的初始化順序Java
- 關於java的初始化順序Java
- c#類的成員初始化順序C#
- 九、 Java程式初始化的順序(二)Java
- 類的成員變數的初始化順序變數
- java類載入順序Java
- Java類的基本執行順序Java
- JVM類載入機制與類初始化順序JVM
- Java的類的例項化順序Java
- Java父子類載入順序Java
- 總結類初始化時的程式碼執行順序
- Java初始化靜態變數的時間順序Java變數
- Java中,類與類,類中的程式碼執行順序Java
- 程式碼說事 之 建立java物件的初始化順序Java物件
- c#物件初始化順序C#物件
- java類內部程式碼執行順序Java
- static程式碼塊、構造程式碼塊、建構函式以及Java類初始化順序C程式函式Java
- Java static變數、作用域、建構函式初始化順序Java變數函式
- DS順序表--類實現
- 類的例項化順序和分析
- css中連結偽類的順序CSS
- C++建構函式初始化順序C++函式
- C++和C#物件初始化順序C++C#物件
- Java實現順序表Java
- 順序表(順序儲存)迴圈佇列類(初始化,入隊,退隊,輸出排頭與排尾指標及元素)佇列指標
- C#類中方法的執行順序C#
- java中帶繼承類的載入順序詳解及實戰Java繼承
- 學Java,Java書籍的最佳閱讀順序Java
- java運算子優先順序Java
- JAVA中取順序號 (轉)Java
- 關於jvm載入類的實現順序JVM