这是一个对于静态初始化块(1),初始化块(2),构造器(3)的加载顺序的测试文件。
总结: 1.创建一个对象:
首先初始化类,从祖先的静态初始化块开始,直到自己的静态初始化块,
然后是初始化该对象,从祖先的初始化块、构造方法开始,直到自己的初始化块和构造方法。
2.静态初始化块执行过一次之后,不论创建多少个对象,都不再执行。
3.每创建一个对象,都会执行初始化对象的操作。
4.初始化块与实例变量都是对对象的初始化操作,执行顺序只和在源程序中的排列顺序有关。
5.同4,静态初始化块与类变量也只和顺序有关。
*/
class Root
{
static{
System.out.println("ROOT的静态初始化块");
}
{
System.out.println("root的普通初始化块");
}
public Root(){
System.out.println("root的无参构造器");
}
}
class Mid extends Root{
static{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid(){
System.out.println("Mid的无参构造器");
}
public Mid(String msg){
//this();
System.out.println("Mid的带参构造器,其参数值为:"+msg);
}
}
class Leaf extends Mid{
static{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf(){
super("调用超类的带参构造器");
System.out.println("Leaf的无参构造器");
}
}
public class Person{
public static void main(String[]args){
new Root();
System.out.println("哈哈哈哈哈,我是一条行分割线");
new Mid();
System.out.println("哈哈哈哈哈,我是一条行分割线");
new Mid("调用Mid的带参构造器");
System.out.println("哈哈哈哈哈,我是一条行分割线");
new Leaf();
System.out.println("*************第二次创建Leaf对象*************");
new Leaf();
}
}
测试结果:
D:\>javac Person.java
D:\>java Person
ROOT的静态初始化块
root的普通初始化块
root的无参构造器
哈哈哈哈哈,我是一条行分割线
Mid的静态初始化块
root的普通初始化块
root的无参构造器
Mid的普通初始化块
Mid的无参构造器
哈哈哈哈哈,我是一条行分割线
root的普通初始化块
root的无参构造器
Mid的普通初始化块
Mid的带参构造器,其参数值为:调用Mid的带参构造器
哈哈哈哈哈,我是一条行分割线
Leaf的静态初始化块
root的普通初始化块
root的无参构造器
Mid的普通初始化块
Mid的带参构造器,其参数值为:调用超类的带参构造器
Leaf的普通初始化块
Leaf的无参构造器
*************第二次创建Leaf对象*************
root的普通初始化块
root的无参构造器
Mid的普通初始化块
Mid的带参构造器,其参数值为:调用超类的带参构造器
Leaf的普通初始化块
Leaf的无参构造器
当只创建两个Leaf对象时,结果如下:
ROOT的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
root的普通初始化块
root的无参构造器
Mid的普通初始化块
Mid的带参构造器,其参数值为:调用超类的带参构造器
Leaf的普通初始化块
Leaf的无参构造器
root的普通初始化块
root的无参构造器
Mid的普通初始化块
Mid的带参构造器,其参数值为:调用超类的带参构造器
Leaf的普通初始化块
Leaf的无参构造器
//执行完所有父类以及子类的static代码块,然后再从父类到子类的初始化块和构造器。