今天做题,突然遇到下面的题目:
private
String baseName =
"base"
;
System. out. println(baseName);
private
String baseName =
"sub"
;
System. out. println (baseName) ;
- null
- sub
- base
之前遇到的问题基本上就是类的加载顺序的问题,但是这次,还附带了在初始化时,方法的覆盖问题。
我们知道,类的加载顺序如下:
- 父类的静态代码块
- 子类的静态代码块
- 父类的非静态代码块
- 父类构造器
- 子类非静态代码块
- 子类构造器
父类的静态代码块是先于构造函数加载的,这是我们都清楚的,但是父类的非静态代码块的加载时间,我们需要进行验证一下:
非静态代码块的加载时机
我们利用上述题目中的代码进行验证,如下:
class Base { private String baseName = "base"; public Base() { callName(); } public void callName() { System.out.println(baseName); } public static void main(String[] args) { Base b = new Base(); } }
执行结果为:base
这说明,在进行构造器调用之前,我们已经完成String类型变量baseName的赋值操作;因此,非静态变量的初始化顺序在调用构造器之前。
方法覆盖与多态
下面我们对这个问题,进行验证,执行该问题的代码,我们可以得到输出结果为:null
这是因为当执行父类构造器方法时,进行callName调用,此时的类是一个Sub类型的类,会优先查找Sub类中是否有该方法,如存在该方法,优先进行调用。当调用Sub类中的callName方法时,因为Sub类中baseName尚未初始化,因此打印出的结果为null;
修改程序代码,将Sub类中的callName方法改为callName1,再次运行程序:
private
String baseName =
"base"
;
System. out. println(baseName);
private
String baseName =
"sub"
;
System. out. println (baseName) ;
此时的输出结果为:base
因为调用callName方法时,Sub类不存在该方法,因此调用Base类中的callName方法,如上一部分所说,Base类中的非静态变量baseName在调用构造器之前已经完成初始化,所以值为base。