静态块,构造块 构造函数以及 静态块调用构造对象的 执行次序
请看一段这些方法或者块的执行代码:
package Test;
public class People {
private String name = "李四";
{
System.out.println("初始化1");
name = "张三";
age = 20;
}
private int age = 30;
static {
System.out.println("静态初始化1");
System.out.println("王二开始");
People people = new People("王二", 50);
System.out.println(people);
System.out.println("王二结束");
}
{
System.out.println("初始化2");
name = "赵四";
}
static {
System.out.println("静态初始化2");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public People(String name, int age) {
super();
System.out.println("有参构造器");
this.name = name;
this.age = age;
}
public People() {
super();
System.out.println("无参构造器");
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "People [name=" + name + ", age=" + age + "]";
}
}
package Test;
public class Main {
public static void main(String[] args) {
System.out.println("tom开始");
People tom = new People("tom", 20);
System.out.println(tom);
System.out.println("tom结束");
System.out.println("jouty开始");
People jouty = new People("jouty", 19);
System.out.println(jouty);
System.out.println("jouty结束");
System.out.println("jerry开始");
People jerry = new People("jerry", 19);
System.out.println(jerry);
System.out.println("jerry结束");
}
}
执行结果:
下面的讨论,我们除去了main方法里面的System.out.println();因为这些是用于我们将其执行过程分开,让我们便于观察
最先执行——静态块(包含“静态块调用构造对象”)
又结果我们可以看到,最先输出的是“静态初始化1”,即静态块最先执行了,因为在类的第一次加载的时候,就会进行静态域的初始化,与实例域一样,除非显示的设置为其他值,否则默认的初始化是0、false或null。他们的执行顺序,按照定义语句时的先后顺序执行
然后执行——构造块
在“静态初始化1”块里面,我们还定义了一个对象实例,但是,后续显示的却是“初始化1”、“初始化2”、“有参构造器”等,直到该name = “王二”;的实例结束; 因为执行是先执行初始化块的,但是静态块又比构造快早,之所以出现“初始化1”、“初始化2”是因为,第一个静态块即“静态初始化1”还没有执行好,所以,后面的静态块都不会执行,所以执行了每一次实例化对象都会执行的构造快,直到构造块结束后,就相当于第一个静态块加载结束了,这个时候才开始加载下一个静态块
最后执行——构造函数
当所有的静态块都加载结束,才开始执行类对象的初始化,即第一个 People Tom = new People(“Tom”,20);而构造块则又是在构造函数执行之前,静态块之后,且构造块是伴随着每一次类对象实例化都会执行的,所以这个Tom的时候,是先执行了“初始化1”、“初始化2”接着才是有参构造函数(有参构造器);
后面的jouty和jerry都是一样的,因为静态块只有在类加载的时候执行,且执行一次,所以后面不会再输出“静态初始化1”、“静态初始化2”,而只会执行构造块“初始化1”、“初始化2”,且是在“有参构造器(或者无参构造起)”之前