目錄java
在程序設計中,讓數據域正確地執行初始化一直是一個亙古不變的真理。
那麼,有哪些手段能夠初始化數據域呢:測試
本篇探討關於Java中的初始化塊的注意點:Java中的初始化塊是類中的一種成員,可是既沒有名字,也沒有標識,不可以被調用,它僅僅只是在建立Java對象時隱式執行初始化。this
{}
包起代碼,被包住的就是初始化代碼,總體就是一個初始化塊。聲明實例變量時指定默認值和普通初始化塊都被看作是對象的初始化代碼,按前後順序執行。設計
若是多個重載的構造器有相同且與傳入形參無關的語句能夠一塊兒提入初始化塊。code
public class NormalBlock { int a = 5; { // a = 6; System.out.println("初始化塊以後的a爲"+a); } // { // int a = 8; // System.out.println("初始化塊中從新定義了一個a?"+a); // } NormalBlock(){ System.out.println("構造器中賦a的值爲"+a); } } class NormalTest{ public static void main(String[] args) { new NormalBlock(); } }
初始化塊以後的a爲5 構造器中賦a的值爲5
能夠看到,在這個例子中,聲明實例變量指定默認值也被看做初始化代碼,且依次執行,先初始化塊,後構造器。(能夠試着調換它們的位置驗證一下哈)orm
初始化塊以後的a爲6 初始化塊中從新定義了一個a?8 構造器中賦a的值爲6
個人疑惑點在於,我一開始覺得,我在第二個代碼塊中定義的和以前同名的變量a是同一個(然而並非)這樣也就算了,初始化代碼以後,執行構造器時,調用了a,那麼這時這個a調用的是哪一個呢,因而產生疑惑,但願知道的小夥伴能夠爲我指點迷津。對象
ilegal forward reference
,即前向引用錯誤,以下圖。{ age = 50; if(age>40) System.out.println("Father類的初始化塊且age>40"); System.out.println("Father類的第一個初始化塊"); } int age =20;
產生緣由:是由於在尚未定義該變量時,就引用了它,因此爲了不這樣的錯誤,儘可能將初始化塊放在成員變量聲明以後。繼承
和普通的對應的就是靜態初始化塊啦,也就是用static修飾的,也稱爲類初始化塊。根據名稱分析,類初始化塊負責對類進行初始化,而普通初始化塊負責對對象執行初始化。it
static{}
的格式包圍對類變量的初始化。關於初始化塊與構造器的前後調用順序,結合代碼來理解一會兒。程序設計
package com.my.pac17; /** * @auther Summerday */ public class A { { System.out.println("A.instance initializer"); } static { System.out.println("A.static initializer"); } public A() { System.out.println("A.A"); } } class B extends A { { System.out.println("B.instance initializer"); } static { System.out.println("B.static initializer"); } public B() { System.out.println("B.B"); } public B(String m) { this(); System.out.println("B.B," + m); } } class C extends B { { System.out.println("C.instance initializer"); } static { System.out.println("C.static initializer"); } public C() { super("ccc"); System.out.println("C.C"); } } class BTest { public static void main(String[] args) { new C(); System.out.println("*******"); new C(); } }
/*測試結果*/ A.static initializer B.static initializer C.static initializer /*類初始化階段,限制性最頂層父類的靜態初始化塊 而後依次向下,直到執行當前類的靜態初始化塊*/ A.instance initializer A.A B.instance initializer B.B//調用B的無參構造器 B.B,ccc//調用B的帶參構造器 C.instance initializer//最後執行C C.C /*對象初始化階段,先執行最頂層父類的初始化塊, 最頂層父類的構造器,而後依次向下,直到執行當前 類的初始化塊、當前類的構造器*/ ******* //不用執行靜態初始化語句 A.instance initializer A.A B.instance initializer B.B B.B,ccc C.instance initializer C.C