Java建構函式(構造器)


建構函式是用於在物件建立後立即初始化物件的程式碼塊。建構函式的結構看起來類似於一個方法。

宣告建構函式

建構函式宣告的一般語法是:

<Modifiers> <Constructor Name>(<parameters list>) throws <Exceptions list> {

}

建構函式的宣告以修飾符開頭。
建構函式可以將其存取修飾符為:publicprivateprotectedpackage-level(無修飾符)。

建構函式名稱與類的名稱相同。建構函式名稱後面是一對括號,可能包括引數。可選地,右括號後面可以是關鍵字throws,其後面是逗號分隔異常列表。

以下程式碼顯示了宣告類Test的建構函式的範例。 類的名稱和建構函式的名稱必須匹配。

public class Test {

  public Test() {
    // Code goes here

  }
}

與方法不同,建構函式沒有返回型別。

使用建構函式

使用一個帶有new操作符的建構函式來在建立新範例之後初始化類的範例。使用new運算子來建立一個物件,建構函式初始化該物件。
以下語句使用Test類別建構函式來初始化Test類的物件:

Test t = new Test();

以下程式碼顯示了如何使用建構函式 -

class Cat {
  public Cat() {
    System.out.println("in constructor...");
  }
}

public class Main {
  public static void main(String[] args) {
    // Create a Cat object and ignore its reference
    new Cat();
    // Create another Cat object and store its reference in c
    Cat c = new Cat();
  }
}

上面的程式碼生成以下結果。

in constructor...
in constructor...

過載建構函式

一個類可以有多個建構函式。 它們稱為過載建構函式。如果一個類有多個建構函式,它們的順序或引數型別都必須與其他建構函式不同。
下面的程式碼宣告兩個建構函式。 一個建構函式不接受引數,另一個接受一個String型別的引數。

class Car {
  // Constructor #1
  public Car() {
    System.out.println("A car  is created.");
  }

  // Constructor #2
  public Car(String name) {
    System.out.println("A car  named " + name + "  is created.");
  }
}

public class Main {
  public static void main(String[] args) {
    Car d1 = new Car(); // Uses Constructor #1
    Car d2 = new Car("My Car"); // Uses Constructor #2
  }
}

上面的程式碼生成以下結果。

每個物件建立表示式呼叫一次建構函式。可以在物件建立的過程中只執行一個建構函式的程式碼一次。

從另一個建構函式呼叫建構函式

建構函式可以呼叫同一類中的另一個建構函式。考慮下面的Test類。 它宣告兩個建構函式; 一個不接受引數,一個接受一個int引數。
必須使用關鍵字this從另一個建構函式呼叫另外一個建構函式。下面的程式碼使用語句「this(1);」從沒有引數的建構函式中呼叫具有int引數的建構函式。

class Test {
  Test() {
    this(1); // OK. Note the use of the keyword this.
  }

  Test(int x) {
  }
}

如果建構函式呼叫另一個建構函式,它必須是建構函式體中的第一個可執行語句。建構函式不能呼叫自身,因為它將導致遞回呼叫。

從建構函式返回

建構函式在其宣告中不能有返回型別。但可以在建構函式體中使用沒有返回表示式的return語句。當一個建構函式中的返回語句被執行時,控制返回給呼叫者,忽略建構函式的其餘程式碼。
以下程式碼顯示了在建構函式中使用return語句的範例。

class Test {
  public Test(int x) {
    if (x < 0) {
      return;
    }

    System.out.println("here");
  }
}

建構函式的存取級別修飾符

建構函式的存取級別決定了可以在物件建立表示式中使用該建構函式的程式。可以為建構函式指定四個存取級別之一:publicprivateprotectedpackage-level(不寫的情況)。下面的程式碼宣告了Test類的四個建構函式。

// Class Test   has  public access level 
public class Test {
  // Constructor #1 - Package-level access
  Test() {
  }

  // Constructor #2 - public access level
  public Test(int x) {
  }

  // Constructor #3 - private access level
  private Test(int x, int y) {
  }

  // Constructor #4 - protected access level
  protected Test(int x, int y, int z) {
  }
}

具有公共(public)存取級別的建構函式可以在程式的任何部分中使用。具有私有(private)存取級別的建構函式只能在宣告它的同一類中使用。具有受保護(protected)存取級別的建構函式可以在具有宣告類的相同包的程式中以及在任何包中的任何子類中使用。具有包級存取許可權的建構函式可以在宣告其類的同一個包中使用。

預設建構函式

如果在定義類時,一個建構函式都不宣告,Java編譯器將向類新增一個建構函式。編譯器新增的建構函式稱為預設建構函式。預設建構函式沒有任何引數。預設建構函式也稱為無引數建構函式。如果類已經有一個建構函式,編譯器就不會新增任何建構函式。