1. 程式人生 > >關於類中new物件與建構函式執行順序的問題

關於類中new物件與建構函式執行順序的問題

     如下有3個類,其中COM是表示元件類別。Root類包含一個COM物件引用,Root中派生出Stem類(即Stem類繼承Root類)。每個類都有一個無引數的建構函式,列印當前的類名。其中Root類中擁有一個靜態程式碼塊。

package com.practise;

public class Try
{
  public static void main(String[] args)
	{
		new Root();
		new Root();
		new Stem();
	}
}

class Root
{
	Root(){System.out.println("this is Root");}
	static 
	{
		System.out.println("我是靜態的");
		//靜態變數是屬於類的,而不是屬於類建立的物件或例項。
		//因為靜態變數被類的所有例項共用,所以非執行緒安全的。
		//通常靜態變數還和關鍵字final一起用,作為所有物件共用的資源或常量。
	}
	COM c;
}
class Stem extends Root
{
	Stem(){System.out.println("this is Stem");}
	COM c=new COM("Stem");
}
class COM
{
	COM(String s){System.out.println("我是COM-----"+s);}
}
    編譯執行這個段程式碼,可以得到如下結果:

/*output:

我是靜態的
this is Root
this is Root
this is Root
我是COM-----Stem
this is Stem

*/

   得到這個結果的原因是什麼呢?首先從類的載入來分析,載入類檔名相同的public類,找到主函式,然後有new Root();此時需要例項化一個Root物件。

   例項化Root物件時,首先應該執行靜態程式碼塊,靜態方法,靜態變數(需要注意的是靜態程式碼塊或者方法以及變數,只會隨著類的載入而只執行一次!而且是所有物件共用的資源或常量),然後申明類中非靜態成員變數,再執行建構函式,因為建構函式中可能會使用類中的成員變數。於是第一行便是列印了“我是靜態的”

,接著是“this is Root”

   第二次例項化Root物件時,便不再執行靜態程式碼塊,於是便申明一個COM類,存在棧中,初始化為null,最後執行建構函式,列印“this is Root”

   第三次是例項化一個Stem物件,在建立Stem物件時,通過extends關鍵字發現它擁有基類Root,此時應該轉到先例項化Stem的基類Root!!因為在繼承關係中,子類繼承了父類中的所有成員變數和方法,依賴於父類,(其實每個子類都擁有父類的內建物件),例項化Root類和上面一樣,建立COM物件,引用為null存在棧中(由於Root類在之前已經進行了兩次例項化,所以不會再執行靜態程式碼塊,所以的靜態程式碼塊都只加載一次),執行建構函式列印“this is Root”

    然後再建立Stem物件,類中無靜態成員,於是先申明成員變數,COM c= new COM(),這個語句表明在申明變數的時候同時也進行了初始化,不再是null!由列印了我是COM---Stem‘可以看出執行了初始化。然後再是建構函式,列印了”this is Stem“

    Java還只算得上是初學者,以上僅是個人在學習過程中的一些理解。歡迎各位發現錯誤並幫助我改正。希望自己better and better!害羞