Java初始化塊及執(zhí)行過程解析
問題:Java對象初始化方式主要有哪幾種?分別是什么?
針對上面的問題,想必大家腦海中首先浮現(xiàn)出的答案是構(gòu)造器,沒錯,構(gòu)造器是Java中常用的對象初始化方式。
還有一種與構(gòu)造器作用非常相似的是初始化塊,它可以對Java對象進(jìn)行初始化操作。下面主要闡述Java的初始化塊及執(zhí)行過程。
Java初始化塊其實(shí)是Java類的成員之一,其語法格式如下:
[修飾符]{
//初始化塊的可執(zhí)行代碼
...
}
初始化塊的修飾符只能是static,使用static修飾符的初始化塊稱為靜態(tài)初始化塊,后面會介紹到。
下面通過一段程序代碼看看創(chuàng)建對象Dog時發(fā)生了什么。
public class Dog { //定義一個初始化塊 { System.out.println("第一個初始化塊"); } //定義第二個初始化塊 { System.out.println("第二個初始化塊"); } //定義無參的構(gòu)造器 public Dog() { System.out.println("Dog的無參構(gòu)造器"); } public static void main(String[] args) { new Dog(); } }
運(yùn)行結(jié)果為:
第一個初始化塊 第二個初始化塊 Dog的無參構(gòu)造器
從運(yùn)行結(jié)果可以看出:當(dāng)創(chuàng)建一個Dog對象時,程序先執(zhí)行初始化塊后執(zhí)行構(gòu)造器,而且兩個初始化的執(zhí)行順序是按照前后順序執(zhí)行的。
由于初始化塊只在創(chuàng)建Java對象時隱士的執(zhí)行(所有的初始化塊全部執(zhí)行),為了讓程序更加的簡潔和可讀性更強(qiáng),一般一個類里最多只有一個初始化塊。
既然初始化塊和構(gòu)造器都是創(chuàng)建對象的時候執(zhí)行,那么它們有什么區(qū)別呢?
從某種程度上來看,初始化塊是構(gòu)造器的補(bǔ)充,與構(gòu)造器不同的是,初始化塊是一段固定執(zhí)行的代碼,不能接收任何的參數(shù),而構(gòu)造器是可以接收參數(shù)的。如果程序中有兩個構(gòu)造器,并且它們有公共的無需接收參數(shù)的代碼,則可以把這些相同的公共代碼放到初始化塊中,提高代碼的可維護(hù)性。
當(dāng)普通初始化塊被static修飾時,則這個初始化塊就是靜態(tài)初始化塊,也被稱為類初始化塊。
普通初始化塊負(fù)責(zé)對對象進(jìn)行初始化,而靜態(tài)初始化塊負(fù)責(zé)對類進(jìn)行初始化,所以靜態(tài)初始化塊總是比普通初始化塊先執(zhí)行。
靜態(tài)初始化塊通常用于對類變量執(zhí)行初始化處理,不能對實(shí)例變量進(jìn)行初始化處理。
靜態(tài)初始化塊也是類的靜態(tài)成員,仍然需要遵循靜態(tài)成員不能訪問非靜態(tài)成員的規(guī)則,包括不能訪問實(shí)例變量和實(shí)例方法。
初始化塊執(zhí)行的時候會一直上溯到j(luò)ava.lang.Object類,先執(zhí)行Object的初始化塊,再執(zhí)行其父類的初始化塊...最后才執(zhí)行該類自己的初始化塊。
下面看下這段代碼的執(zhí)行順序結(jié)果:
class Biology{ static { System.out.println("Biology的靜態(tài)初始化塊"); } { System.out.println("Biology的普通初始化塊"); } public Biology(){ System.out.println("Biology的無參構(gòu)造器"); } } class Animal extends Biology{ static { System.out.println("Animal的靜態(tài)初始化塊"); } { System.out.println("Animal的普通初始化塊"); } public Animal(){ System.out.println("Animal的無參構(gòu)造器"); } public Animal(String name){ this();//調(diào)用同類中的重載構(gòu)造器 System.out.println("Animal的帶參構(gòu)造器,name="+name); } } class Cat extends Animal{ static { System.out.println("Cat的靜態(tài)初始化塊"); } { System.out.println("Cat的普通初始化塊"); } public Cat(){ //調(diào)用父類中帶參數(shù)的構(gòu)造器 super("Java典籍"); System.out.println("Cat的無參構(gòu)造器"); } } public class Test { public static void main(String[] args) { new Cat(); System.out.println("========="); new Cat(); } }
執(zhí)行結(jié)果如下:
Biology的靜態(tài)初始化塊 Animal的靜態(tài)初始化塊 Cat的靜態(tài)初始化塊 Biology的普通初始化塊 Biology的無參構(gòu)造器 Animal的普通初始化塊 Animal的無參構(gòu)造器 Animal的帶參構(gòu)造器,name=Java典籍 Cat的普通初始化塊 Cat的無參構(gòu)造器 ========= Biology的普通初始化塊 Biology的無參構(gòu)造器 Animal的普通初始化塊 Animal的無參構(gòu)造器 Animal的帶參構(gòu)造器,name=Java典籍 Cat的普通初始化塊 Cat的無參構(gòu)造器
從上面的執(zhí)行結(jié)果來看,第一次創(chuàng)建Cat對象時,由于系統(tǒng)還未有Cat對象,因此需要先加載并初始化Cat類,初始化Cat類會先執(zhí)行其頂層父類的靜態(tài)初始化塊,再執(zhí)行其直接父類的靜態(tài)初始化塊,最后才執(zhí)行其本身的靜態(tài)初始化塊。
一旦Cat類初始化成功后,其在虛擬機(jī)中一直存在,當(dāng)?shù)诙卧賱?chuàng)建Cat對象時 無需再對Cat類進(jìn)行初始化。
綜上,一個類初始化的執(zhí)行順序?yàn)椋焊割愳o態(tài)初始化塊,該類靜態(tài)初始化塊,父類普通初始化塊,父類構(gòu)造器,該類普通初始化塊,該類構(gòu)造器。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Java程序執(zhí)行過程及內(nèi)存機(jī)制詳解
- 詳解java中finalize的實(shí)現(xiàn)與相應(yīng)的執(zhí)行過程
- 詳解java中Reference的實(shí)現(xiàn)與相應(yīng)的執(zhí)行過程
- Java中for循環(huán)的執(zhí)行過程分析
- java 異常被catch后 將會繼續(xù)執(zhí)行的操作
- java多線程中執(zhí)行多個程序的實(shí)例分析
- Java如果在try里面執(zhí)行return還會不會執(zhí)行finally
- Java使用多線程異步執(zhí)行批量更新操作方法
- 淺談Java文件被執(zhí)行的歷程
相關(guān)文章
Java的Struts框架中登陸功能的實(shí)現(xiàn)和表單處理器的使用
這篇文章主要介紹了Java的Struts框架中登陸功能的實(shí)現(xiàn)和表單處理器的使用,Struts框架是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下2015-12-12關(guān)于Java for循環(huán)的正確用法介紹
Java里的循環(huán)結(jié)構(gòu)我們可以通過while、do-while、for、foreach等方式實(shí)現(xiàn)循環(huán),這篇文章會把這幾種循環(huán)方式都給大家講解到,但本文主要介紹for循環(huán)的使用,感興趣的同學(xué)可以參考閱讀2023-05-05在IntelliJ IDEA中.idea文件是什么可以刪除嗎
相信有很多小伙伴,在用idea寫java代碼的時候,創(chuàng)建工程總是會出現(xiàn).idea文件,該文件也從來沒去打開使用過,那么它在我們項(xiàng)目里面,扮演什么角色,到底能不能刪除它呢?這篇文章主要介紹了在IntelliJ IDEA中.idea文件是什么可以刪除嗎,需要的朋友可以參考下2024-01-01java實(shí)現(xiàn)的計(jì)算器功能示例【基于swing組件】
這篇文章主要介紹了java實(shí)現(xiàn)的計(jì)算器功能,結(jié)合實(shí)例形式分析了java基于swing組件實(shí)現(xiàn)計(jì)算器功能相關(guān)運(yùn)算操作技巧,需要的朋友可以參考下2017-12-12