我们面试java 尤其 是初中级的时候 这种执行顺序的题 是最多的 这个东西如果想要搞明白 就得 明白 底层 是如何 运作的
执行初始化的 集中情况 < init>方法
1 大家 都知道 在写java 代码的时候都会有一个构造器 就算不写 也会系统默认一个 无参构造器 那么这个构造器 到底是什么的呢 首先看一下 类加载的几个步骤
1 装载:
引导类加载器 扩展类加载器 系统类加载器
2 链接:
验证 准备 解析
3 初始化
而第三步 初始化 就是 我们 平时代码 里面的构造器 这里就表明了为什么 都要有一个构造器 而构造器 是干的么
2 初始化
在 链接的 准备阶段 jvm 会给 所有的全局变量赋值初始值 如果 比如 int 就是 0 String 为空 而 初始化 就是将这个赋值好的 初始值 赋值为我们标记的数值 这也验证了 为什么 全局变量可以 在开始的时候不用 赋值 初始值 而 局部变量不可以 同时 静态变量也不能在 方法内部使用 的原因 并且 方法内部的属性一定 要手动赋值

这里 会有一个 执行初始化的主动 几个因素
1 new 一个对象 执行 cinit init
2 调用静态方法 cinit 执行 init 不执行
3 使用类和接口的静态属性 cinit 执行 init 不执行(如果是本类静态 创建 则执行)
4 通过反射 Class.forName 执行 cinit init
5 调用子类父类 会初始化 执行 cinit(看情况) init
6 实现的接口有default方法 执行 cinit(看情况) init
7 当虚拟机启动的时候我们自己定义的main方法会 优先初始化这个主类 执行 cinit (由静态就会执行) init (不执行 创建才执行)

不会执行 被动

1 子类调用父类的 静态属性 货方法不会被初始化
2 当引用final static 的字段的时候不会被初始化 因为在编译期间就 赋值了
3 使用类的加载器的时候 因为 还没有 进行初始化
4 数组定义类型的时候不会被初始化 比如 Person[]

口诀 是 由父及子 静态先行 如果一个 类没被显示初始化 使用静态方法 或者 属性 只会执行 cinit 如果显示创建 那么 就是 代码块 然后 显示调用的 静态方法 之后是 构造器 静态代码块的执行顺序 主要是 看是在 构造器之前还是 之后 这样在碰到 靠 数据 的 问题的时候 就 比较能应付了