执行顺序问题

main中按顺序执行,当执行到创建类时,如果有继承关系,从最顶层父类一直往下分别执行:

  • 第一先按 静态代码块或静态变量 编写位置顺序执行(谁写在前面就先执行),

  • 第二初按 普通代码块或成员变量 编写位置顺序执行。如果父和子某个成员变量都用某个方法初始化,子覆写了父的这某个方法,子和父成员变量调用这个方法给自己初始化时,不管是子还是父,都是调这个被覆写的方法,也就是子的方法)

  • 第三是构造函数

真实的执行顺序(debug跟踪)

  1. 找到main所在类,按顺序执行 static字段(静态变量或静态块),然后进入main顺序执行。
  2. main中有实例化时,实例化的类有继承关系,即实例化的是子类,则:
    1. 准备阶段:先顺序执行static字段。进入该子类的顶级父类,顺序执行static字段, 然后按继承关系往下找子类,都去顺序执行他们的static字段。
    2. 回到main这实例化处开始实例化:static执行完毕,准备好了,正式进行实例化。
    3. 进入到该子类的构造函数,诶!别急!先不执行该类的一切东西,因为jvm发现该类还继承自他的父类。如果父类又继承自父类的父类,就一直往上找构造函数,且都不执行一切东西,直到顶层父类。
    4. 顶层父类找到了!开始顺序执行顶层父类的非静态字段(非静态块或成员变量),然后是构造函数。然后按继承关系往下找子类,都去顺序执行他们的非静态字段、构造函数。
    5. 该对象的实例化才算真正完成。
    6. 注意!static字段只会执行一次,也就是第一次!!!某类实例化过了,此类的静态字段是不会再走第二次的!!!只会按顶级父类往下的顺序分别走 非静态字段 -> 构造函数
  3. 覆写问题,覆写按最底层子类覆写的方法作为最终方法!如果在父类静态字段执行过程中调用了子类的覆写方法,此方法中访问到的是方法所在类(也就是子类)的变量,此时如果因为还没执行到子类变量的初始化,会得到该变量的默认值。
  4. 某个对象被实例化后,他能访问到的是父类的成员变量还是子类的,取决于他是什么类型的变量,是父类型的变量就可以访问父类型的成员变量,子类型的就是子类型的成员变量。