Java類中的靜態屬性、靜態程式碼塊塊、非靜態屬性、非靜態程式碼塊塊、建構函式在初始化時的執行順序
序言
前幾天在複習J2SE的時候,看到了這個Java類在new的過程中,靜態域、靜態塊、非靜態域、非靜態塊、建構函式的執行順序問題。就想著自己總結寫一下,便於以後查閱
總結:
以下是我整理好的結果;在java類new一個物件的過程中,它們的執行順序如下:
(當java類沒有被繼承時)
1. 實現自身的靜態屬性和靜態程式碼塊。
注意:它們兩個的執行順序根據自身出現的順序決定
2. 實現自身的非靜態屬性和非靜態程式碼塊。
3. 執行自身的建構函式。
(當java類被繼承時,其子類被new物件的執行過程,初始化順序如下:)
1、初始化父類靜態屬性
2、執行父類靜態程式碼塊
3、初始化子類靜態屬性
4、執行子類靜態程式碼塊
5、初始化父類例項變數
6、執行父類動態程式碼塊
7、執行父類構造方法
8、初始化子類例項變數
9、執行子類動態程式碼塊
10、執行子類構造方法
靜態程式碼塊和動態程式碼塊
靜態程式碼塊:
static{
}
動態程式碼塊:
{
}
靜態程式碼塊和非靜態程式碼塊的異同點如下:
相同點:都是JVM載入類時且在建構函式執行之前執行,在類中都可以定義多個,為靜態屬性賦值、執行一些必要的初始化操作
不同點:靜態程式碼塊在非靜態程式碼塊之前執行(靜態程式碼塊執行順序 > 非靜態程式碼塊執行順序)。但是靜態程式碼塊只在第一次new物件時執行一次,之後不再執行。而動態程式碼塊每new一次就執行一次。
例子:
public class Test{
public static void main(String[] args){
MyClass mc = new MyClass();
}
}
class MyClass{
static String str1 = "MyClass 靜態屬性";
static{
//靜態程式碼塊 類級別
System.out.println(str1);
System.out.println("MyClass 靜態程式碼塊");
}
String str2 = "MyClass 非靜態屬性";
{
//動態程式碼塊 物件級別
System.out.println(str2);
System.out.println("MyClass 動態程式碼塊");
}
public MyClass(){
System.out.println("MyClass 構造方法執行");
}
}
結果:
MyClass 靜態屬性
MyClass 靜態程式碼塊
MyClass 非靜態屬性
MyClass 動態程式碼塊
MyClass 構造方法執行
當java類被繼承時,其子類被new物件時,它們的執行順序,如下:
(Sub類為MyClass類的子類)
public class Test{
public static void main(String[] args){
Sub s = new Sub();
}
}
class MyClass{
static String str1 = "MyClass 靜態屬性";
static{
//靜態程式碼塊 類級別
System.out.println(str1);
System.out.println("MyClass 靜態程式碼塊");
}
String str2 = "MyClass 非靜態屬性";
{
//動態程式碼塊 物件級別
System.out.println(str2);
System.out.println("MyClass 動態程式碼塊");
}
public MyClass(){
System.out.println("MyClass 構造方法執行");
}
}
class Sub extends MyClass{
static String str3 = "sub 靜態屬性";
static{
//靜態程式碼塊 類級別
System.out.println(str3);
System.out.println("sub 靜態程式碼塊");
}
String str4 = "sub 非靜態屬性";
{
//動態程式碼塊 物件級別
System.out.println(str4);
System.out.println("sub 動態程式碼塊");
}
public Sub(){System.out.println("sub 構造方法執行");
}
}
結果:
MyClass 靜態屬性
MyClass 靜態程式碼塊
sub 靜態屬性
sub 靜態程式碼塊
MyClass 非靜態屬性
MyClass 動態程式碼塊
MyClass 構造方法執行
sub 非靜態屬性
sub 動態程式碼塊
sub 構造方法執行