Java中,new一個類的對象,類里面的靜態代碼塊、非靜態代碼、無參構造方法、有參構造方法、類的一般方法等部分,它們的執行順序相對來說比較簡單,用程序也很容易驗證。比如新建一個測試父類。
public class FatherTest {
private String name;
FatherTest(){
System.out.println("--父類的無參構造函數--");
}
FatherTest(String name){
this.name=name;
System.out.println("--父類的有參構造函數--"+this.name);
}
static{
System.out.println("--父類的靜態代碼塊--");
}
{
System.out.println("--父類的非靜態代碼塊--");
}
public void speak(){
System.out.println("--父類的方法--");
}
}
加入一個main程序后
public static void main(String[] args) {
System.out.println("--父類主程序--");
FatherTest father=new FatherTest("父親的名字");
father.speak();
}
執行結果為:
--父類的靜態代碼塊--
--父類主程序--
--父類的非靜態代碼塊--
--父類的有參構造函數--父親的名字
--父類的方法—
可以很明顯的看出來執行順序:靜態代碼塊—主程序—非靜態代碼塊—構造函數—一般方法。
如果加入子類的繼承以后,情況就會變得復雜些。比如我們再新建一個測試子類。
public class SonTest extends FatherTest {
private String name;
static{
System.out.println("--子類的靜態代碼塊--");
}
{
System.out.println("--子類的非靜態代碼塊--");
}
SonTest(){
System.out.println("--子類的無參構造函數--");
}
SonTest(String name){
this.name=name;
System.out.println("--子類的有參構造函數--"+this.name);
}
@Override
public void speak(){
System.out.println("--子類Override了父類的方法--");
}
}
然后再加入一個main函數
public static void main(String[] args) {
System.out.println("--子類主程序--");
FatherTest father=new FatherTest("父親的名字");
father.speak();
SonTest son=new SonTest("兒子的名字");
son.speak();
}
執行結果為:
--父類的靜態代碼塊--
--子類的靜態代碼塊--
--子類主程序--
--父類的非靜態代碼塊--
--父類的有參構造函數--父親的名字
--父類的方法--
--父類的非靜態代碼塊--
--父類的無參構造函數--
--子類的非靜態代碼塊--
--子類的有參構造函數--兒子的名字
--子類Override了父類的方法--
加入了子類以后,執行順序有了新的變化,我們可以總結一下。首先第一部分執行的是父類的靜態代碼塊—子類的靜態代碼塊—主程序。這一部分都是執行一次,與建立多少對象沒有關系。第二部分new了一個父類對象,並調用了方法。執行了它的非靜態代碼塊—構造函數—一般方法。第三部分new了一個子類的對象,並調用了方法。執行順序為父類的非靜態代碼塊—父類的無參構造函數,然后是子類的非靜態代碼塊—子類構造函數—子類的方法。