之前都是说的类和类之前的关系,平行的继承的,这次说说关于接口的基本特点。
(一)接口的初始化流程
① 介绍
当一个接口在初始化时,并不要求其父接口都完成了初始化,只有在真正的父接口的时候(如引用接口中锁定义的常量时),才会初始化。
② 列子
结果是
使用了MyChild5的静态变量使用,删除MyParent5的文件,还是可以正常打印6。
③ 修改例子
更改为随机值, final 加进去,运行期必须有常量文件,并不会放置常量池。跟接口还是没任何关系,运行还是没问题,如果是把MyParent5 删除,就会报错。
④ 理解下
本身接口是不允许使用静态代码块的,所以例子不太好举,好好想一下还是可以想通的。
(二)加载流程深入理解
① 例子1
思考结果
② 结果信息
③ 分析
首先调用getInstance的方法,就进入了静态的singleton方法,返回new出来的结果,给静态变量赋值都是0,私有的构造方法,都加1,结果都是1
④ 例子2
思考结果,只是把counter2的位置移动了。
⑤ 结果信息
⑥ 分析
实际开发最没有用的程序,但是学习类加载器特别重要的一个例子,程序逻辑没有改变,就是变量的申明顺序发生了改变, 首先调用getInstance的方法,就进入了静态的singleton方法,主动使用Singleton,既然主动使用,相关的变量和顺序是按照编码的顺序来的,counter1 默认值就是0,private static Singleton singleton = new Singleton(); 会调构造方法 private Singleton() 也会吧counter2 的默认值变成0,也就是在构造方法中 counter1 和 counter2 都等于1,代码继续往下发现counter2 又赋值了变成了0。代码从往下执行。一个类被调用静态方法被主动使用,主动使用初始化阶段前有准备阶段,作用对象的静态成员变量赋初值,赋初值默认并不是你给他的那个值而是系统默认的值,counter1 =0,singleton是null,执行私有的构造方法的时候 用的counter1 被初始化之后的值,counter1是1,counter2是1,然后执行 静态的public static int counter2 =0,又覆盖了之前等于1的值。
PS:最后这个例子对理解初始化阶段和准备阶段非常用意义,本节主要说了接口的初始化,接口初始化的时候并不要求父类接口也接口化,