说明
相信很多人对于java中父子继承关系中,子类实例化调用过程中,代码块的执行顺序都容易忘记或搞混,尤其是java初级笔试题或面试题最容易出这类题目,让人恨得牙痒痒!!!
本文就一次性将其连根铲除,看完你就不会有这个烦恼了,哈哈。
- 先引用一下骨灰级大作《Java编程思想》的复用章节
Java 中万物皆对象,所以加载活动就容易得多。记住每个类的编译代码都存在于它自己独立的文件中。该文件只有在使用程序代码时才会被加载。一般可以说"类的代码在首次使用时加载"。这通常是指创建类的第一个对象,或者是访问了类的 static 属性或方法。构造器也是一个 static 方法尽管它的 static 关键字是隐式的。因此,准确地说,一个类当它任意一个 static 成员被访问时,就会被加载。
首次使用时就是 static 初始化发生时。所有的 static 对象和 static 代码块在加载时按照文本的顺序(在类中定义的顺序)依次初始化。static 变量只被初始化一次。
那么总的来说:
代码块分三种:static静态代码块,匿名代码块(没有名字且没有被static修饰的代码块叫做实例代码块,又称匿名代码块),普通代码块
代码块执行顺序:静态代码块 -> 匿名代码块 -> 构造函数 -> 普通代码块
继承中代码块执行顺序:父类静态块 -->子类静态块 -> 父类匿名代码块 -> 父类构造器 -> 子类匿名代码块 -> 子类构造器
举例
java
class Parent {
{
System.out.println("执行父类第1个匿名代码块");
}
static {
System.out.println("父类静态代码块");
}
{
System.out.println("执行父类第2个匿名代码块");
}
public Parent() {
System.out.println("父类构造函数");
}
public static void parentStaticMethod() {
System.out.println("父类静态方法");
}
}
class Child extends Parent {
static {
System.out.println("子类静态代码块");
}
{
System.out.println("执行子类第1个匿名代码块");
}
public Child() {
System.out.println("子类构造函数");
}
public static void childStaticMethod() {
System.out.println("子类静态方法");
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.childStaticMethod();
}
}
输出:
父类静态代码块
子类静态代码块
执行父类第1个匿名代码块
执行父类第2个匿名代码块
父类构造函数
执行子类第1个匿名代码块
子类构造函数
子类静态方法
解释
在Java中,父子类继承时,静态成员(包括静态方法和静态变量)的加载顺序是由类加载器按照代码的顺序进行的。当一个类被加载时,它的静态成员也会被加载。加载顺序是从上到下,从父类到子类。