构造方法
- 字段初始化:字段初始化是在对象创建时,即在构造函数之前执行的。
- 从上到下的顺序进行初始化
- 可以直接使用常量对成员变量进行初始化
-
也可以使用函数进行初始化
- 注意如果函数有参数则参数必须是已经初始化的
-
实例初始化块:实例初始化块是在对象创建时,在字段初始化之后但在构造函数之前执行的。
- 静态初始化块会优先执行,只能初始化静态变量,在类初次加载时执行(创建对象/访问静态成员)
- 普通初始化块按顺序执行,实例化时执行
class A{ // 静态初始化块 static { System.out.println("static init block A"); } // 普通初始化块 { System.out.println("common init block A"); } // 构造方法 public A() { System.out.println("Constructor without params A"); } }
^0710ee - 初始化顺序
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f1(int marker) {
System.out.println("f1(" + marker + ")");
}
}
class Table {
static Bowl bowl1 = new Bowl(1);
Table() {
System.out.println("Table()");
bowl2.f1(1);
}
void f2(int marker) {
System.out.println("f2(" + marker + ")");
}
static Bowl bowl2 = new Bowl(2);
}
class Cupboard {
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
bowl4.f1(2);
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
static Bowl bowl5 = new Bowl(5);
}
public class StaticInitialization {
public static void main(String [] args) {
System.out.println("main creating new Cupboard()");
new Cupboard();
System.out.println("main creating new Cupboard()");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
/* Output:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
main creating new Cupboard()
Bowl(3)
Cupboard()
f1(2)
main creating new Cupboard()
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
*/
- 静态字段的初始化:首先,类
Table
和Cupboard
的静态字段在首次被访问时初始化。在StaticInitialization
的main
方法执行之前,会初始化这两个类的静态字段,因为它们在main
方法中被用作静态字段。(初始类之前要先对其的静态成员进行初始化) Table.bowl1
初始化,打印Bowl(1)
。Table.bowl2
初始化,打印Bowl(2)
。Cupboard.bowl4
初始化,打印Bowl(4)
。-
Cupboard.bowl5
初始化,打印Bowl(5)
。 -
Table
和Cupboard
的实例初始化:之后,StaticInitialization
中的静态字段table
和cupboard
被初始化。 - 当初始化table时:
- 调用
Table
的构造函数,打印Table()
。 - 在构造函数中调用
bowl2.f1(1)
,打印f1(1)
。
- 调用
-
当初始化cupboard时:
Cupboard.bowl3
初始化,打印Bowl(3)
(这是一个实例字段,所以在每次创建Cupboard
实例时都会初始化)。- 调用
Cupboard
的构造函数,打印Cupboard()
。 - 在构造函数中调用
bowl4.f1(2)
,打印f1(2)
。
-
执行
main
方法: - 打印
main creating new Cupboard()
。 - 创建新的Cupboard实例:
Cupboard.bowl3
初始化,打印Bowl(3)
。- 调用
Cupboard
的构造函数,打印Cupboard()
。 - 在构造函数中调用
bowl4.f1(2)
,打印f1(2)
。
- 打印
main creating new Cupboard()
。 - 再次创建新的Cupboard实例:
Cupboard.bowl3
初始化,打印Bowl(3)
。- 调用
Cupboard
的构造函数,打印Cupboard()
。 - 在构造函数中调用
bowl4.f1(2)
,打印f1(2)
。
- 调用
table.f2(1)
,打印f2(1)
。 -
调用
cupboard.f3(1)
,打印`f3(1) -
在构造函数中调用构造函数
this(目标构造函数参数)
-
只能在构造函数中调用
-
存在继承的构造
- 默认只会调用父类的无参构造函数,如果需要有参构造函数需要显式调用
super(xx)
- 父类->成员(按照声明顺序进行初始化)->自身
public class Test { public static void main(String [] args) { new SubClass(); } } class SuperClass { static int staticSuperVar = initStaticSuperVar(); int instanceSuperVar = initInstanceSuperVar(); static { System.out.println("Static initializer of SuperClass"); } { System.out.println("Instance initializer of SuperClass"); } SuperClass() { System.out.println("Constructor of SuperClass"); } static int initStaticSuperVar() { System.out.println("Static variable of SuperClass"); return 0; } int initInstanceSuperVar() { System.out.println("Instance variable of SuperClass"); return 0; } } class SubClass extends SuperClass { static int staticSubVar = initStaticSubVar(); int instanceSubVar = initInstanceSubVar(); static { System.out.println("Static initializer of SubClass"); } { System.out.println("Instance initializer of SubClass"); } SubClass() { System.out.println("Constructor of SubClass"); } static int initStaticSubVar() { System.out.println("Static variable of SubClass"); return 0; } int initInstanceSubVar() { System.out.println("Instance variable of SubClass"); return 0; } } /* Static variable of SuperClass Static initializer of SuperClass Static variable of SubClass Static initializer of SubClass Instance variable of SuperClass Instance initializer of SuperClass Constructor of SuperClass Instance variable of SubClass Instance initializer of SubClass Constructor of SubClass */