最近一个朋友面试的的时候,碰到一道面向对象的试题,这还不简单哈,三下五除二就完成了,最后竟发现结果是错的,回来自己百度了一下,发现别人也遇到过,小编正好利用这个机会总结下吧!废话不多说,直接上代码看一下试题!
Base类
<span style="font-family:Comic Sans MS;font-size:18px;">/** * @FileName: Base.java * @Package:com.test * @Description: TODO * @author: LUCKY * @date:2015年10月10日 下午1:00:04 * @version V1.0 */ package com.test; /** * @ClassName: Base * @Description: TODO * @author: LUCKY * @date:2015年10月10日 下午1:00:04 */ public class Base { private String baseName="base"; private static String testName="TestBase"; public Base(){ callName(); } public void callName(){ System.out.println(baseName); } } </span>
Sub类
<span style="font-family:Comic Sans MS;font-size:18px;">/** * @FileName: Sub.java * @Package:com.test * @Description: TODO * @author: LUCKY * @date:2015年10月10日 下午1:04:01 * @version V1.0 */ package com.test; /** * @ClassName: Sub * @Description: TODO * @author: LUCKY * @date:2015年10月10日 下午1:04:01 */ class Sub extends Base{ private String baseName="sub"; private static String testName="TestSub"; public void callName(){ System.out.println(baseName); } public static void main(String[] args) { Base base=new Sub(); } } </span>
当小编拿到这份题时,也感觉挺简单的,这不就是父类引用指向子类实例吗?多简单的题哈,直接输出sub字符不就是了吗?可是真正的答案却是null值,小编就感觉到很疑惑,亲自跑遍程序吧!发现果然是自己错了,面向对象的知识还是没有学习好哈!下面来简单的分析下整个执行流程吧!
1.程序启动时,先把程序中的静态变量全部加载到JVM中去,何谓静态变量呢,静态变量是针对于全局的操作,不依赖于某个对象的存在。因此程序启动时,把Base、sub两个类加载到jvm中去,并且每个类中都分配了空间给testName,并且都有值。
2.Base base=new Sub();这我们就知道了,父类引用指向子类操作,因此创建子类的时候,先调用父类的构造函数,也就是public Base(){callName();},当执行到callName()方法的时候,会默认的执行子类中的方法,因此调用子类中的方法callName();
3.调用子类中的callName()方法,输出变量baseName,而此时baseName还没有初始化,只是分配了块空间,因此为null值,所以直接输出null值。
4.执行完父类中的构造函数后,会执行子类的构造函数,此时初始化子类中的baseName为sub,至此整个流程结束。
通过上述分析,我们不难发现,在对象初始化过程中,先会把类加载到JVM中,然后初始化所有的静态变量,最后调用构造函数的时候,会初始化其他变量。
说了这么多,我们把上面的Sub类来变动一下,取出callName()方法后,看看效果如何
<span style="font-family:Comic Sans MS;font-size:18px;">/** * @FileName: Sub.java * @Package:com.test * @Description: TODO * @author: LUCKY * @date:2015年10月10日 下午1:04:01 * @version V1.0 */ package com.test; /** * @ClassName: Sub * @Description: TODO * @author: LUCKY * @date:2015年10月10日 下午1:04:01 */ class Sub extends Base{ private String baseName="sub"; private static String testName="TestSub"; public static void main(String[] args) { Base base=new Sub(); } } </span>
结果也就不多说了,大家自行测试吧!