简介
众所周知,Java的构造函数是实例化对象的时候调用,每次new对象的时候都会调用一次构造函数。但是,如果我们需要在类加载的时候,自动调用并只执行一次初始化,就不能使用常规构造函数了。
有些编程语言提供了静态构造函数pubilc static Person() 的写法,然而Java并不支持,我们可以使用静态代码块来实现同样的效果。
静态代码块
特点:随着类的加载而执行,并且只会执行一次
例子:
public class TestApp {
public static void main(String[] args) throws InterruptedException {
System.out.println(new Date() + ":启动main");
//睡眠3秒,为了证明此时静态代码块还未执行
Thread.sleep(3000);
new Person();
new Person();
}
}
class Person{
static {
System.out.println(new Date() + ":静态代码块");
}
public Person(){
System.out.println(new Date() + ":构造函数");
}
}
上面是个简单的例子,Person 类有 static 静态代码块,也有普通的构造函数。在 main 方法 new 了两个 Person 对象,然后 static 代码只会执行一次。
结果如下,执行顺序为:静态代码块 -> 构造函数
Sat Feb 06 12:12:21 CST 2021:启动main
Sat Feb 06 12:12:24 CST 2021:静态代码块
Sat Feb 06 12:12:24 CST 2021:构造函数
Sat Feb 06 12:12:24 CST 2021:构造函数
思考1:如果Person存在父类,并且父类也存在static静态代码块,那执行顺序是怎样的?
稍微改下代码:
class PersonBase {
static {
System.out.println(new Date() + ":PersonBase 静态代码块");
}
}
class Person extends PersonBase{
static {
System.out.println(new Date() + ":静态代码块");
}
public Person(){
System.out.println(new Date() + ":构造函数");
}
}
结果如下,执行顺序为:父类静态代码块 -> 静态代码块 -> 构造函数
Sat Feb 06 12:13:32 CST 2021:启动main
Sat Feb 06 12:13:35 CST 2021:PersonBase 静态代码块
Sat Feb 06 12:13:35 CST 2021:静态代码块
Sat Feb 06 12:13:35 CST 2021:构造函数
Sat Feb 06 12:13:35 CST 2021:构造函数
思考2:如果父类既存在静态代码块,也存在构造函数,结果如何?
改下 PersonBase 代码:
class PersonBase {
static {
System.out.println(new Date() + ":PersonBase 静态代码块");
}
public PersonBase(){
System.out.println(new Date() + ":PersonBase 构造函数");
}
}
结果如下,执行顺序为:父类静态代码块 -> 子类静态代码块 -> 父类构造函数 -> 子类构造函数
Sat Feb 06 12:18:32 CST 2021:启动main
Sat Feb 06 12:18:35 CST 2021:PersonBase 静态代码块
Sat Feb 06 12:18:35 CST 2021:静态代码块
Sat Feb 06 12:18:35 CST 2021:PersonBase 构造函数
Sat Feb 06 12:18:35 CST 2021:构造函数
Sat Feb 06 12:18:35 CST 2021:PersonBase 构造函数
Sat Feb 06 12:18:35 CST 2021:构造函数