Java的执行代码具有相应的顺序:
类加载阶段:
当JVM第一次主动使用某个类时,系统会在 类准备阶段 为该类的所有静态Field分配内存,所以初次出现的静态Field必须声明数据类型,静态初始化代码里面再次出现时不能声明数据类型,否则会被系统识别为两个Field。在 初始化阶段 则负责 初始化这些静态Field,初始化静态Field就是执行 静态初始化代码 或者 声明静态Field时指定的初始值,它们的执行顺序与源代码中的排列顺序相同。对象创建阶段:
当Java创建一个对象时,系统先为该对象的所有实例Field分配内存(前提是该类已经被加载过了),
所以初次出现的实例Field必须声明数据类型,初始化代码里面再次出现时不能声明数据类型,否则会被系统识别为两个Field。
接着程序开始对这些实例Field执行初始化,其初始化顺序是:先执行初始化块或声明Field时指定的初始值,
它们的执行顺序与源代码中的排列顺序相同,再执行构造器里指定的初始值。
父类静态Field --> 父类静态代码块 --> 子类静态Field --> 子类静态代码块 --> 父类非静态Field --> 父类非静态代码块 --> 父类构造方法 --> 子类非静态Field --> 子类非静态代码块 --> 子类构造方法
public class Test5 { public static void main(String[] args) { Son son = new Son(); System.out.println(son.n); System.out.println(Son.m); } } class Son extends Father { int n = 300; String string = "子类实例变量"; static int m = 1000; static String stringStatic = "子类类变量"; { n = 200; System.out.println("子类非静态代码块"); System.out.println("==========="); } static { m = 2000; System.out.println("子类静态代码块"); System.out.println("==========="); } public Son() { System.out.println("子类构造方法"); System.out.println("==========="); } } class Father { String string = "父类实例变量"; static String stringStatic = "父类类变量"; { System.out.println("父类非静态代码块"); System.out.println("==========="); } static { System.out.println("父类静态代码块"); System.out.println("==========="); } public Father() { System.out.println("父类构造方法"); System.out.println("==============="); } }