Java關於初始化問題的總結(一)

weixin_33866037發表於2017-08-13

Java關於初始化問題的總結(一)

前言

以下針對Java程式中一些初始化問題進行探討與總結

成員初始化

當建立一個類時,類的每個基本型別資料成員保證都有一個初始值,如int,char等資料型別的初值為0,boolean的初值為false。當在類中定義一個物件引用時,如果不進行初始化,此引用會得到初值null。

構造器初始化

1.未使用繼承和多型時:

   (1)初始化順序(不含靜態資料):當新建一個物件時,順序為:成員初始化--->構造器初始化--->方法體初始化。
例項如下:
    class Window {
        private int i ;
        void f() {}
        Window() {
            print("hello wrold");
        }
        public static void main(String[] args) {
            Window w = new Window();
            w.f();
        }
    }

程式執行時先初始化i=0;然後初始化構造器,列印出hello world,然後再執行f()方法

    (2)初始化順序(含靜態資料):順序為:static靜態資料-->成員初始化-->構造器初始化--->方法體初始化.
    例項程式碼:
        public class TestInicail {
        static Table table =new Table();//第一步:建立靜態物件table,進入table中
    public static void main(String[] args) {
        System.out.println("create cup in main");//第五步,才列印輸出
        new Cup();//第六步:進入cup初始化
        }
     }
        class Bow {
            Bow(int i) {
                System.out.println("Bow("+i+")");//第三步:呼叫構造器方法列印輸出
            }
        }
        class Table {
            static Bow bow = new Bow(1);//第二步初始化靜態物件bow,進入bow中
            Table() {
                System.out.println("Table()");//第四步:執行table構造器
            }
        }
        
        class Cup {
            Bow bow2 = new Bow(2);//第七步:初始化bow2,列印出構造器方法
            Cup() {
                System.out.println("CUp()");//第八步:執行cup的構造器
            }
        }
    列印輸出結果依次為:Bow(1),Table(),create cup in main,Bow(2),CUp()
    
    **實際上:初始化順序為先靜態物件(如果它們未因前面的物件建立過程而被初始化),而後是"非靜態物件".

2.使用繼承和多型時:

    初始化實際過程:
    (1)在其他任何事物發生之前,將分配給物件的儲存空間初始化二進位制的零。
    (2)呼叫基類構造器,這個步驟會不斷得反覆遞迴下去,首先是構造這種層次結構的根,然後是下一層匯出類,依次下去。
    (3)按宣告順序呼叫成員的初始化方法。
    (4)呼叫匯出類(繼承類)構造器的主體。

物件的實際建立過程(以Dog類為例)

1.即使沒有顯示使用static關鍵字,構造器實際上也是靜態方法。因此,當首次建立型別為Dog物件的時候(構造器也可看成靜態方法),或者Dog類的靜態方法或域被首次訪問時,java直譯器必需查詢類路徑,以定位Dog.class檔案.(注意這裡訪問構造器方法並不是初始化動作)
2.載入Dog.class,建立一個class物件,然後有關靜態初始化的所有動作都會被執行,靜態初始化只在class物件首次載入時進行一次。
3.當用new Dog()建立物件時,會在堆上為Dog物件分配足夠的儲存空間。
4.分配的儲存空間會被清零,自動將Dog物件中所有基本資料型別都設定成預設值,而引用則設定成null.
5.執行成員變數的初始化。(這裡指成員變數設定有初值,然後進行初始化,而不是指上一步所說的預設值。)
6.執行構造器。(這裡參照構造器初始化中的有關內容)

相關文章