天天看點

執行個體化一個類的對象時的執行順序

下面這個小程式,你能把結果做對嗎? 我就做錯了,對執行個體化對象時的執行順序有些生疏了,希望以後杜絕類似的疏忽。

--Book.java:

import java.io.IOException;

public class Book {

  Book(int marker) {

    System.out.println("Book(" + marker + ")");

  }

  public void f1(int marker) {

    System.out.println("f1(" + marker + ")");

  }

}

--Room.java:

import java.io.IOException;

public class Room {

  static Book book1 = new Book(1);

  public Room() {

    System.out.println("Room()");

    book2.f1(1);

  }

  public static void f2(int marker) {

    System.out.println("f2(" + marker + ")");

  }

  Book book2 = new Book(2);

}

--Shelf.java:

import java.io.IOException;

public class Shelf {

  Book book3 = new Book(3);

  Book book4 = new Book(4);

  public Shelf() {

    System.out.println("Shelf()");

    book4.f1(2);

  }

  void f3(int marker) {

    System.out.println("f3(" + marker + ")");

  }

  static Book book5 = new Book(5);

}

--InitializationTest.java:

import java.io.IOException;

class InitializationTest {

  public static void main(String[] args) {

    System.out.println("Creating new Shelf() in main");

        Room.f2(1);

        new Shelf();

    System.out.println("Creating new Shelf() in main");

    new Shelf();

    new InitializationTest();

  }

  static Room room = new Room();

   Shelf cupboard = new Shelf();

   InitializationTest()

   {

           System.out.println("InitializationTest()");

   }

}

執行結果是:

Book(1)

Book(2)

Room()

f1(1)

Creating new Shelf() in main

f2(1)

Book(5)

Book(3)

Book(4)

Shelf()

f1(2)

Creating new Shelf() in main

Book(3)

Book(4)

Shelf()

f1(2)

Book(3)

Book(4)

Shelf()

f1(2)

InitializationTest()

仔細看一看上面的流程,可以概括成幾個要點:

1.在執行個體化一個類的對象時,先要執行個體化該類的成員變量,再執行該類的構造函數。

2. 在執行個體化一個類的成員變量時,先要執行個體化靜态成員變量,再執行個體化非靜态成員變量。

3. 一個類的靜态成員變量隻執行個體化一次,即隻有一個拷貝,在該類的所有對象中共享。

4. 執行一個類的靜态成員函數時,該類的對象并沒有生成,是以,隻會執行個體化該類的靜态成員變量,而不會執行個體化非靜态成員變量,也不會執行構造函數。

另外,上面4個java檔案都沒有指定包名,可以讓他們在同一個目錄中,這樣在使用“javac”指令編譯檔案以及“java”指令執行檔案時就不需要顯示的指明classpath的路徑。

而如果他們分屬不同的package,比如說Book.java、Room.java、Shelf.java在同一個包com1中, 而InitializationTest.java在另一個包com2中,那麼我們使用“javac”編譯InitializationTest.java時,就要使用-classpath指明com1所在的位置,當然InitializationTest.java要import com1.*.

然後,使用“java”指令來執行InitializationTest.class時,也要用-classpath指明包com2的位置。

是以,使用預設包名和自定義包名來編譯時還是有差別的,隻是大家容易忽略罷了。