我们先来做如下测试:
无父类时:
class Test{private int i = printf("i");
private static int j = printf("j");
{
System.out.println("非静态代码块执行");
}
static{
System.out.println("static块执行");
}
Test()
{
System.out.println("构造函数执行");
}
private static int printf(String s) {
System.out.println(s+" 执行");
return 0;
}
//主函数
public static void main(String str[])
{
Test a=new Test();
}
}
执行结果:
j 执行
static块执行
i 执行
非静态代码块执行
构造函数执行
结论:先初始化静态属性或静态代码块(顺序取决于代码的顺序),再初始化非静态属性和非静态代码块(顺序取决于代码的顺序),最后执行构造函数。
有父类时:
package test;
class TestA{
private int i = printf("父类i");
private static int j = printf("父类静态j");
{
System.out.println("父类非静态代码块执行");
}
static{
System.out.println("父类static块执行");
}
TestA()
{
System.out.println("父类构造函数执行");
}
private static int printf(String s) {
System.out.println(s+" 执行");
return 0;
}
}
class TestB extends TestA{
private int i = printf("子类i");
private static int j = printf("子类静态j");
{
System.out.println("子类非静态代码块执行");
}
static{
System.out.println("子类static块执行");
}
TestB()
{
System.out.println("子类构造函数执行");
}
private static int printf(String s) {
System.out.println(s+" 执行");
return 0;
}
//主函数
public static void main(String str[])
{
TestB b=new TestB();
}
}
执行结果:
父类静态j 执行
父类static块执行
子类静态j 执行
子类static块执行
父类i 执行
父类非静态代码块执行
父类构造函数执行
子类i 执行
子类非静态代码块执行
子类构造函数执行
结论:第一步,先初始化静态属性和静态代码块(先父类的静态,再子类的静态)。
第二步,再初始化父类的非静态属性和非静态代码块及构造函数。
第三部,再在初始化子类的非静态属性和非静态代码块及构造函数