關(guān)于Java中代碼塊的執(zhí)行順序
前言
先說(shuō)總結(jié):
父類(lèi)靜態(tài)字段 —> 父類(lèi)靜態(tài)代碼塊 —> 子類(lèi)靜態(tài)字段 —> 子類(lèi)靜態(tài)代碼塊 —> 父類(lèi)成員變量和非靜態(tài)塊(順序加載) —> 父類(lèi)構(gòu)造函數(shù) —> 子類(lèi)成員變量和非靜態(tài)塊(順序加載) —> 子類(lèi)構(gòu)造函數(shù)
- 靜態(tài)代碼塊:用staitc聲明,jvm加載類(lèi)時(shí)執(zhí)行,僅執(zhí)行一次。
- 構(gòu)造代碼塊:類(lèi)中直接用{}定義,每一次創(chuàng)建對(duì)象時(shí)執(zhí)行。
- 執(zhí)行順序優(yōu)先級(jí):靜態(tài)塊,main(),構(gòu)造塊,構(gòu)造方法。
構(gòu)造函數(shù)
public HelloA(){//構(gòu)造函數(shù) }
關(guān)于構(gòu)造函數(shù),以下幾點(diǎn)要注意:
- 對(duì)象一建立,就會(huì)調(diào)用與之相應(yīng)的構(gòu)造函數(shù),也就是說(shuō),不建立對(duì)象,構(gòu)造函數(shù)時(shí)不會(huì)運(yùn)行的。
- 構(gòu)造函數(shù)的作用是用于給對(duì)象進(jìn)行初始化。
- 一個(gè)對(duì)象建立,構(gòu)造函數(shù)只運(yùn)行一次,而一般方法可以被該對(duì)象調(diào)用多次。
構(gòu)造代碼塊
{//構(gòu)造代碼塊 }
關(guān)于構(gòu)造代碼塊,以下幾點(diǎn)要注意:
- 構(gòu)造代碼塊的作用是給對(duì)象進(jìn)行初始化。
- 對(duì)象一建立就運(yùn)行構(gòu)造代碼塊了,而且優(yōu)先于構(gòu)造函數(shù)執(zhí)行。這里要強(qiáng)調(diào)一下,有對(duì)象建立,才會(huì)運(yùn)行構(gòu)造代碼塊,類(lèi)不能調(diào)用構(gòu)造代碼塊的,而且構(gòu)造代碼塊與構(gòu)造函數(shù)的執(zhí)行順序是前者先于后者執(zhí)行。
- 構(gòu)造代碼塊與構(gòu)造函數(shù)的區(qū)別是:構(gòu)造代碼塊是給所有對(duì)象進(jìn)行統(tǒng)一初始化,而構(gòu)造函數(shù)是給對(duì)應(yīng)的對(duì)象初始化,因?yàn)闃?gòu)造函數(shù)是可以多個(gè)的,運(yùn)行哪個(gè)構(gòu)造函數(shù)就會(huì)建立什么樣的對(duì)象,但無(wú)論建立哪個(gè)對(duì)象,都會(huì)先執(zhí)行相同的構(gòu)造代碼塊。也就是說(shuō),構(gòu)造代碼塊中定義的是不同對(duì)象共性的初始化內(nèi)容。
靜態(tài)代碼塊
static {//靜態(tài)代碼塊 }
關(guān)于靜態(tài)代碼塊,要注意的是:
- 它是隨著類(lèi)的加載而執(zhí)行,只執(zhí)行一次,并優(yōu)先于主函數(shù)。具體說(shuō),靜態(tài)代碼塊是由類(lèi)調(diào)用的。類(lèi)調(diào)用時(shí),先執(zhí)行靜態(tài)代碼塊,然后才執(zhí)行主函數(shù)的。
- 靜態(tài)代碼塊其實(shí)就是給類(lèi)初始化的,而構(gòu)造代碼塊是給對(duì)象初始化的。
- 靜態(tài)代碼塊中的變量是局部變量,與普通函數(shù)中的局部變量性質(zhì)沒(méi)有區(qū)別。
- 一個(gè)類(lèi)中可以有多個(gè)靜態(tài)代碼塊。
public class Test { staitc int cnt=6; static { cnt += 9; } public static void main(String[] args) { System.out.println(cnt); } static { cnt /= 3; } } // 5
Java類(lèi)初始化順序
對(duì)于一個(gè)類(lèi)的情況
public class HelloA { public HelloA(){//構(gòu)造函數(shù) System.out.println("A的構(gòu)造函數(shù)"); } {//構(gòu)造代碼塊 System.out.println("A的構(gòu)造代碼塊"); } static {//靜態(tài)代碼塊 System.out.println("A的靜態(tài)代碼塊"); } public static void main(String[] args) { } } // A的靜態(tài)代碼塊
public class HelloA { public HelloA(){//構(gòu)造函數(shù) System.out.println("A的構(gòu)造函數(shù)"); } {//構(gòu)造代碼塊 System.out.println("A的構(gòu)造代碼塊"); } static {//靜態(tài)代碼塊 System.out.println("A的靜態(tài)代碼塊"); } public static void main(String[] args) { HelloA a=new HelloA(); } } // A的靜態(tài)代碼塊 // A的構(gòu)造代碼塊 // A的構(gòu)造函數(shù)
public class HelloA { public HelloA(){//構(gòu)造函數(shù) System.out.println("A的構(gòu)造函數(shù)"); } {//構(gòu)造代碼塊 System.out.println("A的構(gòu)造代碼塊"); } static {//靜態(tài)代碼塊 System.out.println("A的靜態(tài)代碼塊"); } public static void main(String[] args) { HelloA a=new HelloA(); HelloA b=new HelloA(); } } // A的靜態(tài)代碼塊 // A的構(gòu)造代碼塊 // A的構(gòu)造函數(shù) // A的構(gòu)造代碼塊 // A的構(gòu)造函數(shù)
對(duì)于一個(gè)類(lèi)而言,按照如下順序執(zhí)行:
- 執(zhí)行靜態(tài)代碼塊
- 執(zhí)行構(gòu)造代碼塊
- 執(zhí)行構(gòu)造函數(shù)
對(duì)于靜態(tài)變量、靜態(tài)初始化塊、變量、初始化塊、構(gòu)造器,它們的初始化順序依次是靜態(tài)變量、靜態(tài)初始化塊)>(變量、初始化塊)>構(gòu)造器。
public class InitialOrderTest { /* 靜態(tài)變量 */ public static String staticField = "靜態(tài)變量"; /* 變量 */ public String field = "變量"; /* 靜態(tài)初始化塊 */ static { System.out.println( staticField ); System.out.println( "靜態(tài)初始化塊" ); } /* 初始化塊 */ { System.out.println( field ); System.out.println( "初始化塊" ); } /* 構(gòu)造器 */ public InitialOrderTest(){ System.out.println( "構(gòu)造器" ); } public static void main( String[] args ){ new InitialOrderTest(); } } // 靜態(tài)變量 // 靜態(tài)初始化塊 // 變量 // 初始化塊 // 構(gòu)造器
對(duì)于繼承情況
public class HelloA { public HelloA(){//構(gòu)造函數(shù) System.out.println("A的構(gòu)造函數(shù)"); } {//構(gòu)造代碼塊 System.out.println("A的構(gòu)造代碼塊"); } static {//靜態(tài)代碼塊 System.out.println("A的靜態(tài)代碼塊"); } } public class HelloB extends HelloA{ public HelloB(){//構(gòu)造函數(shù) System.out.println("B的構(gòu)造函數(shù)"); } {//構(gòu)造代碼塊 System.out.println("B的構(gòu)造代碼塊"); } static {//靜態(tài)代碼塊 System.out.println("B的靜態(tài)代碼塊"); } public static void main(String[] args) { HelloB b=new HelloB(); } } // A的靜態(tài)代碼塊 // B的靜態(tài)代碼塊 // A的構(gòu)造代碼塊 // A的構(gòu)造函數(shù) // B的構(gòu)造代碼塊 // B的構(gòu)造函數(shù)
當(dāng)涉及到繼承時(shí),按照如下順序執(zhí)行:
- 執(zhí)行父類(lèi)的靜態(tài)代碼塊,并初始化父類(lèi)靜態(tài)成員變量
- 執(zhí)行子類(lèi)的靜態(tài)代碼塊,并初始化子類(lèi)靜態(tài)成員變量
- 執(zhí)行父類(lèi)的構(gòu)造代碼塊,執(zhí)行父類(lèi)的構(gòu)造函數(shù),并初始化父類(lèi)普通成員變量
- 執(zhí)行子類(lèi)的構(gòu)造代碼塊, 執(zhí)行子類(lèi)的構(gòu)造函數(shù),并初始化子類(lèi)普通成員變量
class Parent { /* 靜態(tài)變量 */ public static String p_StaticField = "父類(lèi)--靜態(tài)變量"; /* 變量 */ public String p_Field = "父類(lèi)--變量"; protected int i = 9; protected int j = 0; /* 靜態(tài)初始化塊 */ static { System.out.println( p_StaticField ); System.out.println( "父類(lèi)--靜態(tài)初始化塊" ); } /* 初始化塊 */ { System.out.println( p_Field ); System.out.println( "父類(lèi)--初始化塊" ); } /* 構(gòu)造器 */ public Parent(){ System.out.println( "父類(lèi)--構(gòu)造器" ); System.out.println( "i=" + i + ", j=" + j ); j = 20; } } public class SubClass extends Parent { /* 靜態(tài)變量 */ public static String s_StaticField = "子類(lèi)--靜態(tài)變量"; /* 變量 */ public String s_Field = "子類(lèi)--變量"; /* 靜態(tài)初始化塊 */ static { System.out.println( s_StaticField ); System.out.println( "子類(lèi)--靜態(tài)初始化塊" ); } /* 初始化塊 */ { System.out.println( s_Field ); System.out.println( "子類(lèi)--初始化塊" ); } /* 構(gòu)造器 */ public SubClass(){ System.out.println( "子類(lèi)--構(gòu)造器" ); System.out.println( "i=" + i + ",j=" + j ); } /* 程序入口 */ public static void main( String[] args ){ System.out.println( "子類(lèi)main方法" ); new SubClass(); } } // 父類(lèi)--靜態(tài)變量 // 父類(lèi)--靜態(tài)初始化塊 // 子類(lèi)--靜態(tài)變量 // 子類(lèi)--靜態(tài)初始化塊 // 子類(lèi)main方法 // 父類(lèi)--變量 // 父類(lèi)--初始化塊 // 父類(lèi)--構(gòu)造器 // i=9, j=0 // 子類(lèi)--變量 // 子類(lèi)--初始化塊 // 子類(lèi)--構(gòu)造器 // i=9,j=20
子類(lèi)的靜態(tài)變量和靜態(tài)初始化塊的初始化是在父類(lèi)的變量、初始化塊和構(gòu)造器初始化之前就完成了。
靜態(tài)變量、靜態(tài)初始化塊,變量、初始化塊初始化了順序取決于它們?cè)陬?lèi)中出現(xiàn)的先后順序。
到此這篇關(guān)于關(guān)于Java中代碼塊的執(zhí)行順序的文章就介紹到這了,更多相關(guān)Java代碼塊執(zhí)行內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java學(xué)生信息管理系統(tǒng)設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了java學(xué)生信息管理系統(tǒng)設(shè)計(jì),學(xué)生信息添加進(jìn)入數(shù)據(jù)庫(kù)的事務(wù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11IntelliJ IDEA遠(yuǎn)程Debug Linux的Java程序,找問(wèn)題不要只會(huì)看日志了(推薦)
這篇文章主要介紹了IntelliJ IDEA遠(yuǎn)程Debug Linux的Java程序,找問(wèn)題不要只會(huì)看日志了,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Knife4j的請(qǐng)求示例當(dāng)中有很多空白行的問(wèn)題解決辦法
這篇文章主要介紹了Knife4j的請(qǐng)求示例當(dāng)中有很多空白行的問(wèn)題解決辦法,按正常來(lái)說(shuō)不應(yīng)該有上方的空白,當(dāng)然如果只是查看我也不至于非要解決他,主要是假如接口是json傳參,調(diào)試界面都沒(méi)辦法修改參數(shù),遇到同樣問(wèn)題的同學(xué)可以參考閱讀本文2024-09-09Java如何使用遞歸查詢多級(jí)樹(shù)形結(jié)構(gòu)數(shù)據(jù)(多級(jí)菜單)
這篇文章主要介紹了Java如何使用遞歸查詢多級(jí)樹(shù)形結(jié)構(gòu)數(shù)據(jù)(多級(jí)菜單),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07Springboot2.x結(jié)合Mabatis3.x下Hikari連接數(shù)據(jù)庫(kù)報(bào)超時(shí)錯(cuò)誤
本文針對(duì)Springboot2.x與Mybatis3.x結(jié)合使用時(shí),Hikari連接數(shù)據(jù)庫(kù)出現(xiàn)超時(shí)錯(cuò)誤的問(wèn)題進(jìn)行了深入分析,并提供了一系列有效的解決方法,感興趣的可以了解一下2023-11-11java設(shè)計(jì)日歷可視化的詳細(xì)步驟記錄
這篇文章主要給大家介紹了關(guān)于java設(shè)計(jì)日歷可視化的相關(guān)資料,通過(guò)自定義的CircleLabel類(lèi)來(lái)突出顯示今天的日期,并使用BorderLayout布局管理窗口組件,文章詳細(xì)描述了各個(gè)類(lèi)和方法的設(shè)計(jì)思想和實(shí)現(xiàn)邏輯,需要的朋友可以參考下2024-12-12java數(shù)據(jù)結(jié)構(gòu)關(guān)于棧的實(shí)例應(yīng)用
大家好,本篇文章主要講的是java數(shù)據(jù)結(jié)構(gòu)關(guān)于棧的實(shí)例應(yīng)用,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12