問題:Java對象初始化方式主要有哪幾種?分別是什麼?
針對上面的問題,想必你們腦海中首先浮現出的答案是構造器,沒錯,構造器是Java中經常使用的對象初始化方式。html
還有一種與構造器做用很是類似的是初始化塊,它能夠對Java對象進行初始化操做。下面主要闡述Java的初始化塊及執行過程。java
Java初始化塊實際上是Java類的成員之一,其語法格式以下:微信
[修飾符]{this
//初始化塊的可執行代碼spa
...code
}htm
初始化塊的修飾符只能是static,使用static修飾符的初始化塊稱爲靜態初始化塊,後面會介紹到。對象
下面經過一段程序代碼看看建立對象Dog時發生了什麼。blog
public class Dog { //定義一個初始化塊 { System.out.println("第一個初始化塊"); } //定義第二個初始化塊 { System.out.println("第二個初始化塊"); } //定義無參的構造器 public Dog() { System.out.println("Dog的無參構造器"); } public static void main(String[] args) { new Dog(); } }
運行結果爲:虛擬機
第一個初始化塊 第二個初始化塊 Dog的無參構造器
從運行結果能夠看出:當建立一個Dog對象時,程序先執行初始化塊後執行構造器,並且兩個初始化的執行順序是按照先後順序執行的。
因爲初始化塊只在建立Java對象時隱士的執行(全部的初始化塊所有執行),爲了讓程序更加的簡潔和可讀性更強,通常一個類裏最多隻有一個初始化塊。
既然初始化塊和構造器都是建立對象的時候執行,那麼它們有什麼區別呢?
從某種程度上來看,初始化塊是構造器的補充,與構造器不一樣的是,初始化塊是一段固定執行的代碼,不能接收任何的參數,而構造器是能夠接收參數的。若是程序中有兩個構造器,而且它們有公共的無需接收參數的代碼,則能夠把這些相同的公共代碼放到初始化塊中,提升代碼的可維護性。
當普通初始化塊被static修飾時,則這個初始化塊就是靜態初始化塊,也被稱爲類初始化塊。
普通初始化塊負責對對象進行初始化,而靜態初始化塊負責對類進行初始化,因此靜態初始化塊老是比普通初始化塊先執行。
靜態初始化塊一般用於對類變量執行初始化處理,不能對實例變量進行初始化處理。
靜態初始化塊也是類的靜態成員,仍然須要遵循靜態成員不能訪問非靜態成員的規則,包括不能訪問實例變量和實例方法。
初始化塊執行的時候會一直上溯到java.lang.Object類,先執行Object的初始化塊,再執行其父類的初始化塊...最後才執行該類本身的初始化塊。
下面看下這段代碼的執行順序結果:
class Biology{ static { System.out.println("Biology的靜態初始化塊"); } { System.out.println("Biology的普通初始化塊"); } public Biology(){ System.out.println("Biology的無參構造器"); } } class Animal extends Biology{ static { System.out.println("Animal的靜態初始化塊"); } { System.out.println("Animal的普通初始化塊"); } public Animal(){ System.out.println("Animal的無參構造器"); } public Animal(String name){ this();//調用同類中的重載構造器 System.out.println("Animal的帶參構造器,name="+name); } } class Cat extends Animal{ static { System.out.println("Cat的靜態初始化塊"); } { System.out.println("Cat的普通初始化塊"); } public Cat(){ //調用父類中帶參數的構造器 super("Java典籍"); System.out.println("Cat的無參構造器"); } } public class Test { public static void main(String[] args) { new Cat(); System.out.println("========="); new Cat(); } }
執行結果以下:
Biology的靜態初始化塊 Animal的靜態初始化塊 Cat的靜態初始化塊 Biology的普通初始化塊 Biology的無參構造器 Animal的普通初始化塊 Animal的無參構造器 Animal的帶參構造器,name=Java典籍 Cat的普通初始化塊 Cat的無參構造器 ========= Biology的普通初始化塊 Biology的無參構造器 Animal的普通初始化塊 Animal的無參構造器 Animal的帶參構造器,name=Java典籍 Cat的普通初始化塊 Cat的無參構造器
從上面的執行結果來看,第一次建立Cat對象時,因爲系統還未有Cat對象,所以須要先加載並初始化Cat類,初始化Cat類會先執行其頂層父類的靜態初始化塊,再執行其直接父類的靜態初始化塊,最後才執行其自己的靜態初始化塊。
一旦Cat類初始化成功後,其在虛擬機中一直存在,當第二次再建立Cat對象時 無需再對Cat類進行初始化。
綜上,一個類初始化的執行順序爲:父類靜態初始化塊,該類靜態初始化塊,父類普通初始化塊,父類構造器,該類普通初始化塊,該類構造器。
歡迎關注微信公衆號【Java典籍】,收看更多Java技術乾貨!關注即送java全套資料一份
▼微信掃一掃下圖↓↓↓二維碼關注
原文出處:https://www.cnblogs.com/bingyimeiling/p/11529403.html