new一個對象的初始化過程


###############################

今天總結一下,new對象的初始化過程。

###############################

首先,當不含static成員時,先看一下案例圖:

如圖所示,我們先定義相關類,Building,House(繼承Building),Villa(繼承House),同時,House有成員變量LivingRoom,LivingRoom有成員變量Bed和Desk。

具體代碼實現如下:

 1 //建築
 2 class Building {
 3     public Building() {
 4         System.out.println("Building");
 5     }
 6 }
 7 //房子
 8 class House extends Building{
 9     public LivingRoom livingRoom = new LivingRoom();//卧室
10     public House() {
11         System.out.println("House");
12     }
13 } 
14 //別墅
15 class Villa extends House{
16     public Villa () {
17         System.out.println("Villa");
18     }
19 }
20 //卧室
21 class LivingRoom {
22     public Bed bedFirst = new Bed();//
23     public Desk deskFirst = new Desk();//桌子
24     
25     public LivingRoom () {
26         System.out.println("LivingRoom");
27     }
28 }
29 //
30 class Bed {
31     public Bed () {
32         System.out.println("Bed");
33     }
34 }
35 //桌子
36 class Desk {
37     public Desk () {
38         System.out.println("Desk");
39     }
40 }
41 此時,我們new Villa():
42 public class InitializeDemo {
43     @Test
44     public void testInitialize() {
45         Villa villa = new Villa();
46     }
47 }
48 執行結果為:
49 Building
50 Bed
51 Desk
52 LivingRoom
53 House
54 Villa

 

  在此案例中,我們在創建Villa對象時,會先試着創建Villa的父類House的對象,但House也有父類Building,Building還有父類object。因此,實際上,本類會先創建object對象並初始化,在object對象創建並初始化后,會創建building對象,building對象沒有成員變量,所以直接執行構造器,打印出building。

  接着,開始創建house對象,house對象有成員變量livingRoom,因此,會先初始化livingRoom,創建livingRoom時,也會先創建livingRoom的父類object對象並初始化沒其次再創建livingRoom實例,livingroom同樣有兩個成員變量bed和desk,因而會按兩個成員變量的定義順序,先后創建bed和desk。初始化成員變量成功后,執行livingroom的構造器,打印livingroom。初始化livingroom成功后,開始執行house的構造器,打印house。

  最后,在house初始化成功后,執行了Villa的構造器,打印出Villa。

  初始化成功。

其次,當有static成員時

 1 class Family {
 2     Family (Class className) {
 3         System.out.println("創建Family對象");
 4         System.out.println(className.getName());
 5     }
 6 }
 7 class Person {
 8     Person() {
 9         System.out.println("創建Person對象");
10     }    
11     public static Family family = new Family(Person.class);
12     static {
13         System.out.println("執行Person靜態代碼塊");
14     }
15     {
16         System.out.println("執行Person代碼塊");
17     }
18 } 
19 public class Student extends Person {    
20 public Student() {
21         System.out.println("創建student對象");
22     }
23     {
24         System.out.println("執行Student代碼塊");
25     }
26     static {
27         System.out.println("執行Student靜態代碼塊");
28     }
29     public static Family staticFamily = new Family(Student.class);
30     @Test
31     public void test() {
32         System.out.println("=============");
33     }
34     public Family family = new Family(Student.class);
35 }
36 執行結果:
37 創建Family對象
38 com.tca.thinkInJava.chap7.Person
39 執行Person靜態代碼塊
40 執行Student靜態代碼塊
41 創建Family對象
42 com.tca.thinkInJava.chap7.Student
43 執行Person代碼塊
44 創建Person對象
45 執行Student代碼塊
46 創建Family對象
47 com.tca.thinkInJava.chap7.Student
48 創建student對象

 

  1.首先在執行@test方法時,必須創建student的實例對象。

  2.要創建student的實例對象,第一步先加載student父類person和student類的字節碼,並對相關靜態成員變量進行初始化,執行靜態代碼塊。

  3.首先加載父類person字節碼,靜態成員變量public static family ,family優於靜態代碼塊前聲明,所以先對靜態成員變量family進行初始化。創建family對象,打印“創建family對象”,“xxxxxx”。

  4.加載完person字節碼后,再加載student字節碼。靜態代碼塊再靜態成員public static family staticfamily之前聲明,所以先執行靜態代碼塊,打印“執行student靜態代碼塊”,在進行成員變量初始化,執行“創建family對象”,“xxxxxxxxxx”。

  5.創建student父類person的實例對象,創建實例對象時,先進行非靜態成員變量初始化和代碼塊的執行,在執行構造器方法。所以先打印“執行person代碼塊”,再打印“創建person對象”。父類對象創建和初始化完畢。

  6.創建子類對象student,先進行非靜態成員變量初始化和代碼塊的執行,在執行構造方法。代碼塊的聲明再非靜態成員變量聲明之前,所以先執行代碼塊,打印“執行student代碼塊”,再對family進行初始化,創建family對象,打印“創建family對象”,“xxxxxxxxxxx”。

  7.執行test測試方法。

 

總結:

  當不含static成員時,我們new一個對象A時,首先會先創建A類的父類B的實例對象,如果B類仍有C類,會先創建父類C的對象,以此類推,是一個遞歸創建的過程;當該類的父類對象已經全部創建並初始化時,會對該類進行創建和初始化。但在對該類進行初始化時,會先初始該類對象的成員變量,再執行該類的構造方法。成員變量的初始化和代碼塊的執行順序,由它們聲明順序決定的,按順序依次初始化或執行,但均在構造器方法之前執行。

  當有static成員時,在該類第一次被JVM加載時,靜態成員變量只會被初始化一次,靜態代碼塊只會被執行一次。會先加載父類字節碼,再加載子類字節碼,如果有創建某類的實例對象,也是在該類的父類和該類的字節碼加載完成之后,才會實例化該類父類的實例對象和該類的實例對象。靜態成員變量的初始化和靜態代碼塊的執行順序,是由它們的聲明順序決定的,按順序依次初始化或執行。


免責聲明!

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



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