1. 程式人生 > >構造方法、類的初始化塊以及類欄位的初始化順序

構造方法、類的初始化塊以及類欄位的初始化順序

構造方法

首先,以下程式碼為何無法通過編譯?哪兒出錯了?
    public class Test {

        public static void main(String[] args) {

            Foo obj1 = new Foo();

        }

    }

    class Foo {

        int value;

        public Foo (int initValue) {

        value = initValue;

        }

    }
  • 推出的結論:
    如果類提供了一個自定義的構造方法,將導致系統不再提供預設構造方法。

1. 多建構函式

  • 同一個類可以有多個建構函式,多個建構函式之間通過引數來區分。這是方法過載的一個例項。

  • 建構函式之間可以相互呼叫

  •     class Fruit {
                int grams;
                int calsPerGram;
                Fruit() {
                    this(55,10);
                }
                Fruit(int g,int c){
                    grams=g;
                    calsPerGram=c;
                }
        }
    

類的初始化塊

  • 可以在類中使用“{”和“}”將語句包圍起來,直接將其作為類的成員。

  • 類的這種“沒有名字”的“成員”,多用於初始化類的欄位。

  • public class Test {
            public int value=200;
            {
                value=100;          // 類的初始化塊
            }
    }

​ 如果一個類中既有初始化塊,又有構造方法,同時還設定了欄位的初始值,誰說了算?

    class InitializeBlockClass {
        {
          field = 200;
        }
        public
int field = 100; public InitializeBlockClass(int value) { this.field = value; } public InitializeBlockClass() { } }

這是一個生造出來展示Java語法特性的示例類,在實際開發中不要這樣寫程式碼,應該儘量保證一個欄位只初始化一次!

​ 如果使用上面定義的類,思考一下程式碼的輸出結果:

    public static void main(String[] args) {
      InitializeBlockClass obj = new InitializeBlockClass();
      System.out.println(obj.field);  //?
      obj = new InitializeBlockClass(300);
      System.out.println(obj.field);  //?
    }

規律(類欄位的初始化順序)

  1. 執行類成員定義時指定的預設值或類的初始化塊,到底執行哪一個要看哪一個“排在前面”。
  2. 執行類的建構函式。

類的初始化塊不接收任何的引數,而且只要一建立類的物件,它們就會被執行。因此,適合於封裝那些“物件建立時必須執行的程式碼”。