構造方法、類的初始化塊以及類欄位的初始化順序
阿新 • • 發佈:2019-02-11
構造方法
首先,以下程式碼為何無法通過編譯?哪兒出錯了?
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); //?
}
規律(類欄位的初始化順序)
- 執行類成員定義時指定的預設值或類的初始化塊,到底執行哪一個要看哪一個“排在前面”。
- 執行類的建構函式。
類的初始化塊不接收任何的引數,而且只要一建立類的物件,它們就會被執行。因此,適合於封裝那些“物件建立時必須執行的程式碼”。