Thứ tự của khởi tạo class trong Java
Sau khi khai báo một class và khởi tạo đối tượng cho class đó trong java, thứ tự khởi tạo sẽ là:
- Class cha (supper class). [1]
- Thuộc tính static (static field). [2]
- Khối khởi tạo static (initial static block). [3]
- Thuộc tính của đối tượng (instance field). [4]
- Khối khởi tạo của đối tượng (initial block). [5]
- Hàm khởi tạo (Constructor). [6]
Note:
Nhớ [1], [2], [3], [4], [5], [6] để mình giải thích phía dưới nha.
Tìm hiểu qua ví dụ sau:
- Ex1: Khai báo và khởi tạo class Parent.
public class Parent { private String strParent = "init field"; { System.out.println(strParent); strParent = "new value by initial block"; } public Parent(String strParent) { this.strParent = strParent; System.out.println(this.strParent); } public Parent() { this("new Value by constructor that's passed a String parameter"); System.out.println(strParent); } public static void main () { Parent p = new Parent(); }
}
- Kết quả sẽ là:
// 1: init field
// 2: new value by initial block
// 3: new Value by constructor that's passed a String parameter
-
Giải thích:
Khi khởi tạo một đối tượng thì:
Bước 1: Thuộc tính của instance sẽ được khởi tạo trước [4]. Field hay Attribute được khai báo và khởi tạo và gán giá trị đầu tiên. Bước 2: Sau khi khai báo và gán giá trị ở bước 1. Khối khởi tạo của đối tượng (block) [5] sẽ được chạy và gán lại giá trị. Bước 3: Tiếp theo, hàm khởi tạo sẽ chạy sau cùng [6]. Nhưng vì ở đây hàm khởi tạo không có tham số lại gọi hàm khởi tạo có tham số, nên hàm khởi tạo có tham số sẽ được chạy và in giá trị của `strParent`.
- Ex2: Khai báo 1 class Child extends từ class Parent
public class Parent { private String strParent = "init field"; { System.out.println(strParent); strParent = "new value by initial block"; } public Parent(String strParent) { System.out.println(this.strParent); this.strParent = strParent; } public Parent() { this("new Value by constructor that's passed a String parameter"); System.out.println(strParent); }
} public class Child extends Parent { private String strChild = "init strChild field"; private static String strStatic = "init strStatic field"; { System.out.println(strChild); // init strChild field strParent = "new value by initial block"; } static { System.out.println(strStatic); // init strStatic field strStatic = "new value by static initial block"; } public Parent(String strChild) { System.out.println(strChild); // new value by initial block System.out.println(strStatic); // new value by static initial block this.strChild = strChild; } public static void main () { Parent p = new Parent("newest string"); System.out.println(strChild); // newest string }
}
- Kết quả sẽ là:
parent class
// 1: init field
// 2: new value by initial block
// 3: new Value by constructor that's passed a String parameter
child class
// 4: init strStatic field
// 5: init strChild field
// 6: new value by initial block
// 7: new value by static initial block
// 8: newest string
-
Giải thích:
Khi khởi tạo một đối tượng thì:
Bước 1: khởi tạo và in giá trị của class cha trước [1] (Ex1). Bước 2: Khởi tạo static field [2]. Bước 3: Khối khởi tạo static sẽ chạy [3]. Bước 4: Khởi tạo instance field [4]. Bước 5: Khối khởi tạo sẽ chạy [5]. Bước 6: Hàm constructor chạy [6].