我们可以将执行顺序大致看作:
1. 静态成员 //静态的域或方法只在加载类时执行一次
2.初始化块
3. 构造函数
其实初始化块和构造函数可以看成一个整体,(执行构造函数之前先执行这个类的初始化块)。当然在执行子类之前先执行父类相应的方法。(另外需要注意的一点是在执行子类的构造方法之前会先执行父类的默认构造函数即无参构造函数)
在我们学习之前,我们先来看一段代码:
public class Employee {
⑴private String name = "lisi";
⑵{
System.out.println("初始化1");
name = "wangwu";
age = 20;
}
⑶private int age = 30;
⑷static {
System.out.println("静态初始化1");
System.out.println("id0:" + Employee.id);
id = 40;
System.out.println("id1:" + Employee.id);
System.out.println("liuliu开始");
Employee employee = new Employee("liuliu", 50);
System.out.println(employee);
System.out.println("liuliu id:" + employee.getId());
System.out.println("liuliu结束");
}
⑸private static int id = 30;
⑹{
System.out.println("初始化2");
name = "zhaosi";
age = 40;
}
⑺static {
System.out.println("id2:" + Employee.id);
System.out.println("静态初始化2");
id = 80;
System.out.println("id3:" + Employee.id);
}
public static int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employee(String name, int age) {
super();
System.out.println("有參構造器");
this.name = name;
this.age = age;
}
public Employee() {
super();
System.out.println("無參構造器");
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + "]";
}
}
public static void main(String[] args) {
System.out.println("tom开始");
Employee tom = new Employee("tom", 20);
System.out.println(tom);
System.out.println(tom.getId());
System.out.println("tom结束");
System.out.println("jouty开始");
Employee jouty = new Employee("jouty", 19);
System.out.println(jouty);
System.out.println(jouty.getId());
System.out.println("jouty结束");
}
你觉得最后输出结果会是什么呢?不妨自己先试一试!
最后输出为
然后我们来分析一下:
1.输出**“tom开始”**
2.初始化tom对象,输出**“静态初始化1”:
定义tom对象,调用类employee,首先执行第一个static块,输出了“静态初始化1”及"id0:0"(虽然之后定义了id的静态变量为30,但是在加载类的时候,只是将变量的声明提前了,并未对它赋值,所以输出的是id的默认值0);
然后赋值id=40,输出“id1:40”;然后输出“liuliu开始”,然后初始化employee对象,按顺序执行了(1),(2)输出“初始化1”,(3),(6)输出“初始化2”,然后执行构造函数,输出“有参构造器”;
然后回到之前static块中,输出employee对象(即执行其tostring方法),输出“Employee【name=liuliu,age=50】”;然后输出“liuliu id:40”;最后“liuliu结束”;
3.然后执行(5)
4.然后执行(7):
输出(5)所执行的赋值,即输出“id2:30”;
然后输出“静态初始化2”;
执行id=80;输出“id3:80”;至此,就已经执行完了类中的所有静态的域和方法了;
5.然后执行类中的非静态变量和方法,块:
按顺序执行(1),(2)输出“初始化1”,(3),(6)输出“初始化2”,然后执行构造函数,输出“有参构造器”;
返回主函数main()中,输出tom对象(即执行其tostring方法),输出“Employee【name=tom,age=20】”;
6.输出id的值“80”;输出“tom结束”和“jouty开始”;
7.开始初始化jouty对象:
按顺序执行(1),(2)输出“初始化1”,(3),(6)输出“初始化2”,然后执行构造函数,输出“有参构造器”;
返回主函数main()中,输出jouty对象(即执行其tostring方法),输出“Employee【name=jouty,age=19】”;
8…输出id的值“80”;输出“jouty结束”**