Java提高篇——靜態代碼塊、構造代碼塊、建構函式以及Java類初始化順序,建構函式java

來源:互聯網
上載者:User

Java提高篇——靜態代碼塊、構造代碼塊、建構函式以及Java類初始化順序,建構函式java

靜態代碼塊:用staitc聲明,jvm載入類時執行,僅執行一次
構造代碼塊:類中直接用{}定義,每一次建立對象時執行。
執行順序優先順序:靜態塊,main(),構造塊,構造方法。

建構函式
public HelloA(){//建構函式    }

關於建構函式,以下幾點要注意:
1.對象一建立,就會調用與之相應的建構函式,也就是說,不建立對象,建構函式時不會啟動並執行。
2.建構函式的作用是用於給對象進行初始化。
3.一個對象建立,建構函式只運行一次,而一般方法可以被該對象調用多次。

構造代碼塊
{//構造代碼塊    }

關於構造代碼塊,以下幾點要注意:

靜態代碼塊
static {//靜態代碼塊    }

關於靜態代碼塊,要注意的是:

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類初始化順序## 對於一個類的情況

例子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:

 1 public class InitialOrderTest { 2         /* 靜態變數 */ 3     public static String staticField = "靜態變數"; 4         /* 變數 */ 5     public String field = "變數"; 6         /* 靜態初始化塊 */ 7     static { 8         System.out.println( staticField ); 9         System.out.println( "靜態初始化塊" );10     }11         /* 初始化塊 */12     {13         System.out.println( field );14         System.out.println( "初始化塊" );15     }16         /* 構造器 */17     public InitialOrderTest()18     {19         System.out.println( "構造器" );20     }21 22 23     public static void main( String[] args )24     {25         new InitialOrderTest();26     }27 }

運行以上代碼,我們會得到如下的輸出結果:

## 對於繼承情況

例子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的建構函式

當涉及到繼承時,按照如下順序執行:

例子6:

 1 class Parent { 2         /* 靜態變數 */ 3     public static String p_StaticField = "父類--靜態變數"; 4          /* 變數 */ 5     public String    p_Field = "父類--變數"; 6     protected int    i    = 9; 7     protected int    j    = 0; 8         /* 靜態初始化塊 */ 9     static {10         System.out.println( p_StaticField );11         System.out.println( "父類--靜態初始化塊" );12     }13         /* 初始化塊 */14     {15         System.out.println( p_Field );16         System.out.println( "父類--初始化塊" );17     }18         /* 構造器 */19     public Parent()20     {21         System.out.println( "父類--構造器" );22         System.out.println( "i=" + i + ", j=" + j );23         j = 20;24     }25 }26 27 public class SubClass extends Parent {28          /* 靜態變數 */29     public static String s_StaticField = "子類--靜態變數";30          /* 變數 */31     public String s_Field = "子類--變數";32         /* 靜態初始化塊 */33     static {34         System.out.println( s_StaticField );35         System.out.println( "子類--靜態初始化塊" );36     }37        /* 初始化塊 */38     {39         System.out.println( s_Field );40         System.out.println( "子類--初始化塊" );41     }42        /* 構造器 */43     public SubClass()44     {45         System.out.println( "子類--構造器" );46         System.out.println( "i=" + i + ",j=" + j );47     }48 49 50         /* 程式入口 */51     public static void main( String[] args )52     {53         System.out.println( "子類main方法" );54         new SubClass();55     }56 }

結果:

父類--靜態變數
父類--靜態初始化塊
子類--靜態變數
子類--靜態初始化塊
子類main方法
父類--變數
父類--初始化塊
父類--構造器
i=9, j=0
子類--變數
子類--初始化塊
子類--構造器
i=9,j=20

子類的靜態變數和靜態初始化塊的初始化是在父類的變數、初始化塊和構造器初始化之前就完成了。靜態變數、靜態初始化塊,變數、初始化塊初始化了順序取決於它們在類中出現的先後順序。

### 分析
  • (1)訪問SubClass.main(),(這是一個static方法),於是裝載器就會為你尋找已經編譯的SubClass類的代碼(也就是SubClass.class檔案)。在裝載的過程中,裝載器注意到它有一個基類(也就是extends所要表示的意思),於是它再裝載基類。不管你創不建立基類對象,這個過程總會發生。如果基類還有基類,那麼第二個基類也會被裝載,依此類推。

  • (2)執行根基類的static初始化,然後是下一個衍生類別的static初始化,依此類推。這個順序非常重要,因為衍生類別的“static初始化”有可能要依賴基類成員的正確初始化。

  • (3)當所有必要的類都已經裝載結束,開始執行main()方法體,並用new SubClass()建立對象。

  • (4)類SubClass存在父類,則調用父類的建構函式,你可以使用super來指定調用哪個建構函式。基類的構造過程以及構造順序,同衍生類別的相同。首先基類中各個變數按照字面順序進行初始化,然後執行基類的建構函式的其餘部分。

  • (5)對子類成員資料按照它們聲明的順序初始化,執行子類建構函式的其餘部分。

參考文章連結:

java-靜態代碼塊,構造代碼塊,建構函式

Java類初始化順序

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.