关于java中静态代码块和非静态代码块的调用顺序
先贴上实例:
首先是一个父类,在这个父类里,有静态代码块,非静态代码块,构造函数。
public class Father {
static {
System.out.println("父类静态代码块");
}
{
System.out.println("父类非静态代码块");
}
public Father() {
System.out.println("父类构造函数");
}
}
下面是子类继承自上面的父类,同样有静态代码块,非静态代码块,构造函数,在main函数里构造一个子类对象。
public class Son extends Father{
static {
System.out.println("子类静态代码块");
}
{
System.out.println("子类非静态代码块");
}
public Son() {
System.out.println("子类构造函数");
}
public void test_son() {
System.out.println("test_son调用成功");
}
public static void main(String[] args) {
Son a = new Son();
}
}
这是运行结果
父类静态代码块
子类静态代码块
父类非静态代码块
父类构造函数
子类非静态代码块
子类构造函数
可以明显地看出它们的调用顺序。
值得注意的是,静态代码块在主程序运行时候一定会被调用,且只调用一次,比如,我改动一下主函数:
public static void main(String[] args) {
System.out.println("我什么都没调用\n");
}
}
结果会是:
父类静态代码块
子类静态代码块
我什么都没调用
可以明显看出,结果中静态代码块被调用了,但我并没有实例化父类对象或者子类对象。
总结
1.类中的静态代码块在程序运行时一定会调用并且仅调用一次。父类优先于子类。
2.非静态调用优先于构造函数,构造子类时先调用父类的非静态->父类构造函数->子类的非静态->子类构造函数
扩展
我又尝试了一下向上转型或向下转型会如何
以下是向下转型,仅改动main函数
/**向上转型*/
Father f = new Son();
f.test_Father();
运行结果
父类静态代码块
子类静态代码块
父类非静态代码块
父类构造函数
子类非静态代码块
子类构造函数
test_Father调用成功
向上转型还是很好理解的,和实例化子类对象是一样的调用顺序。
以下是向下转型
Father f = new Father();
if(f instanceof Son) {
//向下转型
Son s = (Son)f;
s.test_Father();
s.test_son();
}
结果如下
父类静态代码块
子类静态代码块
父类非静态代码块
父类构造函数
可以看出,向下转型后的对象并没能完成对父类方法和子类方法的调用,具体原因我目前还没有了解…以后有机会我了解了会在这里加上的。