java初始化順序


1、在任何事情發生之前,將分配給對象的存儲空間初始化為0;

2、從根基類開始遞歸,按照類中的聲明順序調用靜態代碼塊、靜態成員的初始化方法。

但是有兩個例外:

    • 定義為final非靜態基本數據類型的成員變量此時也會被初始化;
    • 有且只有定義為final非靜態的String成員變量,采用的“=”賦值初始化會被執行(非new)。我們知道java中沒有

         操作符重載這一概念,能通過“=”直接賦值的類只有String或Integer等java內部實現的final類。奇怪的是這里只有String能夠初始化,

         Integer等不行,具體只能看java虛擬機的實現了微笑

3、從根基類開始,按照類中的聲明順序調用非靜態代碼塊和非靜態成員(除了2中的幾個final特例)初始化方法,再調用構造函數,然后向子類遞歸初始化;

 

注意:父類構造函數內部調用具有多態行為的函數將導致無法預測的結果,因為此時會調用子類override后的方法,而此時所有子類的

非靜態成員可能還沒有初始化,不會得到我們想要的結果。

測試平台:win10(32) + jre1.8.0_73 + eclipse

測試代碼:

基類

public class BaseInit {
    static { 
        System.out.println("<<<基類靜態代碼塊>>>"); 
    } 
 
    public BaseInit() { 
        System.out.println("<<<基類構造函數>>>");


        //調用子類的override函數,訪問子類未初始化的非靜態成員變量
        dangerTest();
    } 
 
    { 
        System.out.println("<<<基類非靜態代碼塊>>>");
    }
  

    //need override
    public void dangerTest() { }
}

子類:

public class DeriveInit extends BaseInit {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new DeriveInit();
    }
   

    /**
     * 構造函數
     */
    public DeriveInit() {  
        System.out.println("<<<子類構造函數>>>");


        if(testNonStatic == 555)
        {
            System.out.println("成員變量已經初始化");
        }
    }
   
    /**
     * 靜態
     */
    static private int testStatic = 100;


    static {
        System.out.println("<<<子類靜態代碼塊>>>");
       
        if(testStatic == 100)
        {
            System.out.println("同一類內靜態按照聲明順序初始化");
        }
    } 
   
    /**
     * 非靜態
     */
    private int testNonStatic = 555;


    {
        System.out.println("<<<子類非靜態代碼塊>>>");
       
        if(testNonStatic == 555)
        {
            System.out.println("同一類內非靜態按照聲明順序初始化"); 
        }
    }
   

/**
* 在基類中訪問子類的非靜態成員變量
*/
private int derive0 = 888;
final private int derive1 = 888;
final private Integer derive2 = 888;
final private String derive3 = new String("Hello World");
final private String derive4 = "Hello World";

@Override
public void dangerTest()
{
    System.out.println("子類成員變量derive0 = " + derive0);
    System.out.println("子類成員變量derive1 = " + derive1);
    System.out.println("子類成員變量derive2 = " + derive2);
    System.out.println("子類成員變量derive3 = " + derive3);
    System.out.println("子類成員變量derive4 = " + derive4);
}

}

運行結果:

<<<基類靜態代碼塊>>>
<<<子類靜態代碼塊>>>
同一類內靜態代碼按照聲明順序初始化
<<<基類非靜態代碼塊>>>
<<<基類構造函數>>>
子類成員變量derive0 = 0
子類成員變量derive1 = 888
子類成員變量derive2 = null
子類成員變量derive3 = null
子類成員變量derive4 = Hello World
<<<子類非靜態代碼塊>>>
同一類內非靜態代碼按照聲明順序初始化
<<<子類構造函數>>>
成員變量已經初始化

 

 

 

--僅供參考,歡迎交流--


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM