java类初始化顺序_Java 类的初始化顺序
靜態代碼塊:用staitc聲明,jvm加載類時執行,僅執行一次
構造代碼塊:類中直接用{}定義,每一次創建對象時執行
執行順序優先級:靜態塊,main(),構造塊,構造方法
1. 構造函數
public HelloWorld(){ }關于構造函數,以下幾點要注意: 1.對象一建立,就會調用與之相應的構造函數,也就是說,不建立對象,構造函數時不會運行的。 2.構造函數的作用是用于給對象進行初始化。 3.一個對象建立,構造函數只運行一次,而一般方法可以被該對象調用多次。
2. 構造代碼塊
或稱代碼塊.
{//構造代碼塊 }關于構造代碼塊,以下幾點要注意:
3. 靜態代碼塊
static{//靜態代碼塊 }關于靜態代碼塊,要注意的是:
運行結果:
54. Java 類初始化順序
4.1 對于一個類的情況
例 1:
public class HelloA {public HelloA(){//構造函數System.out.println("A的構造函數"); }{//構造代碼塊System.out.println("A的構造代碼塊"); }static {//靜態代碼塊System.out.println("A的靜態代碼塊"); }public static void main(String[] args) {} }運行結果:
A的靜態代碼塊例 2:
public class HelloA {public HelloA(){//構造函數System.out.println("A的構造函數"); }{//構造代碼塊System.out.println("A的構造代碼塊"); }static {//靜態代碼塊System.out.println("A的靜態代碼塊"); }public static void main(String[] args) {HelloA a=new HelloA(); } }運行結果:
A的靜態代碼塊 A的構造代碼塊 A的構造函數例 3:
public class HelloA {public HelloA(){//構造函數System.out.println("A的構造函數"); }{//構造代碼塊System.out.println("A的構造代碼塊"); }static {//靜態代碼塊System.out.println("A的靜態代碼塊"); }public static void main(String[] args) {HelloA a=new HelloA();HelloA b=new HelloA();} }運行結果:
A的靜態代碼塊 A的構造代碼塊 A的構造函數 A的構造代碼塊 A的構造函數對于一個類而言,按照如下順序執行:
對于靜態變量、靜態代碼化塊、變量、構造代碼塊、構造器,它們的初始化順序依次是(靜態變量、靜態代碼塊)>(變量、構造代碼塊)> 構造器, 見下例.
例子 4:
public class InitialOrderTest {/* 靜態變量 */public static String staticField = "靜態變量";/* 變量 */public String field = "變量";/* 靜態初始化塊 */static {System.out.println( staticField );System.out.println( "靜態代碼" );}/* 初始化塊 */{System.out.println( field );System.out.println( "構造代碼塊" );}/* 構造器 */public InitialOrderTest(){System.out.println( "構造器" );}public static void main( String[] args ){new InitialOrderTest();} }運行結果:
靜態變量 靜態代碼塊 變量 構造代碼塊 構造器4.2 對于繼承情況
例子 5:
public class HelloA {public HelloA(){//構造函數System.out.println("A的構造函數"); }{//構造代碼塊System.out.println("A的構造代碼塊"); }static {//靜態代碼塊System.out.println("A的靜態代碼塊"); } } public class HelloB extends HelloA{public HelloB(){//構造函數System.out.println("B的構造函數"); }{//構造代碼塊System.out.println("B的構造代碼塊"); }static {//靜態代碼塊System.out.println("B的靜態代碼塊"); }public static void main(String[] args) {HelloB b=new HelloB(); } }運行結果:
A的靜態代碼塊 B的靜態代碼塊 A的構造代碼塊 A的構造函數 B的構造代碼塊 B的構造函數當涉及到繼承時,按照如下順序執行:
執行子類的構造代碼塊, 執行子類的構造函數,并初始化子類普通成員變量
Java 初始化順序圖:
例子 6:
class Parent {/* 靜態變量 */public static String p_StaticField = "父類--靜態變量";/* 變量 */public String p_Field = "父類--變量";protected int i = 9;protected int j = 0;/* 靜態初始化塊 */static {System.out.println( p_StaticField );System.out.println( "父類--靜態初始化塊" );}/* 初始化塊 */{System.out.println( p_Field );System.out.println( "父類--初始化塊" );}/* 構造器 */public Parent(){System.out.println( "父類--構造器" );System.out.println( "i=" + i + ", j=" + j );j = 20;} }public class SubClass extends Parent {/* 靜態變量 */public static String s_StaticField = "子類--靜態變量";/* 變量 */public String s_Field = "子類--變量";/* 靜態初始化塊 */static {System.out.println( s_StaticField );System.out.println( "子類--靜態初始化塊" );}/* 初始化塊 */{System.out.println( s_Field );System.out.println( "子類--初始化塊" );}/* 構造器 */public SubClass(){System.out.println( "子類--構造器" );System.out.println( "i=" + i + ",j=" + j );}/* 程序入口 */public static void main( String[] args ){System.out.println( "子類main方法" );new SubClass();} }運行結果:
父類--靜態變量 父類--靜態初始化塊 子類--靜態變量 子類--靜態初始化塊 子類main方法 父類--變量 父類--初始化塊 父類--構造器 i=9, j=0 子類--變量 子類--初始化塊 子類--構造器 i=9,j=20子類的靜態變量和靜態初始化塊的初始化是在父類的變量、初始化塊和構造器初始化之前就完成了。靜態變量、靜態初始化塊,變量、初始化塊初始化了順序取決于它們在類中出現的先后順序。
4.3 總結
訪問 SubClass.main(),(這是一個 static 方法),于是裝載器就會為你尋找已經編譯的 SubClass 類的代碼(也就是 SubClass.class 文件)。在裝載的過程中,裝載器注意到它有一個基類(也就是 extends 所要表示的意思),于是它再裝載基類。不管你創不創建基類對象,這個過程總會發生。如果基類還有基類,那么第二個基類也會被裝載,依此類推。
執行根基類的 static 初始化,然后是下一個派生類的 static 初始化,依此類推。這個順序非常重要,因為派生類的“static初始化”有可能要依賴基類成員的正確初始化。
當所有必要的類都已經裝載結束,開始執行 main() 方法體,并用 new SubClass() 創建對象。
類 SubClass 存在父類,則調用父類的構造函數,你可以使用 super 來指定調用哪個構造函數。基類的構造過程以及構造順序,同派生類的相同。首先基類中各個變量按照字面順序進行初始化,然后執行基類的構造函數的其余部分。
對子類成員數據按照它們聲明的順序初始化,執行子類構造函數的其余部分。
5. References
[1] Java-靜態代碼塊,構造代碼塊,構造函數
[2] Java類初始化順序
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的java类初始化顺序_Java 类的初始化顺序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python秒数变分钟_python时间
- 下一篇: java 获取子线程_Java 主线程获