父类子类初始化问题

携程Java工程师的移到面向对象面试题

 

public class Base {
    private String baseName = "base";

    public Base() {
        callName();
    }

    public void callName() {
        System.out.println(baseName);
    }

    static class Sub extends Base {
        private String baseName = "sub";

        public void callName() {
            System.out.println(baseName);
        }
    }

    public static void main(String[] args) {
        Base b = new Sub();
    }
}

输出是null

 未老莫还乡 的评论:

 

【不要在构造器里调用可能被重载的虚方法,这是极度危险的】。构造器的初始化顺序大概是 父类静态块 子类静态块 父类初始化语句 父类构造函器 子类初始化语句 子类构造器。父类构造器执行的时候,调用了子类的重载方法,然而子类的类字段还在刚初始化的阶段,刚完成内存布局,只能输出null。

 

 

ihuning 的精华评论:

 

看我大师归来:

 

1. Base b = new Sub();

 

2. Base b = 直接忽略,从 new Sub();开始

 

3. 类加载器加载 Base,Sub 类到jvm;

 

4. 为Base,Sub 类中的两个属性baseName 分配存储空间,但是不初始化;

 

注意:属性的初始化时放在构造器中,按照代码顺序执行的。

 

5. new Sub会调用Sub的无参构造器,而在这个构造器中会隐式调用父类Base的无参构造器;

 

6. 父类Base的构造器中代码本质是

 

public Base()

{

baseName = "base";

callName();

}

 

即父类的属性baseName 的值为base。但为何输出null,骚年别急。

 

7. 因为父类构造器方法是在子类中调用的,即大环境是子类。此时,调用的方法callName()当然是指子类的方法。而这个方法打印的属性baseName当然也是子类的。那现在子类的属性baseName的值是多少呢?答案是null.因为此时子类Sub的构造器内代码本质是:

 

super();

baseName="sub";

此时baseName="sub"还没执行。

 

因此,左后的值当然是null.

 

个人总结:

main方法之前先把父类初始化,包括父类static块,然后子类static块(因为main方法中new了子类)

然后父类默认的构造函数,然后子类构造函数

 

 1 public class Base {
 2     private static String baseName = "base";
 3 
 4     public Base() {
 5         System.out.println("construct-parent-before");
 6         callName();
 7         System.out.println("construct-parent-after");
 8     }
 9 
10     public void callName() {
11         System.out.println(baseName);
12     }
13 
14     static class Sub extends Base {
15         private static String baseName = "sub";
16         public Sub(){
17             System.out.println("construct-sub");
18         }
19         public void callName() {
20             System.out.println(baseName);
21         }
22     }
23 
24     public static void main(String[] args) {
25         new Sub();
26     }
27 }

输出:

construct-parent-before
sub
construct-parent-after
construct-sub

posted on 2015-10-11 11:42  天娱邪神  阅读(508)  评论(0编辑  收藏  举报