论坛首页 入门技术论坛

构造函数中调用其他的方法会产生的问题

浏览 2271 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-01-14  
看代码
class Base{
    private int val;
    //构造函数,调用lookup()方法
    Base() {
        val = lookup();
    }

    public int lookup() {
        return 5;
    }
    public int value(){
        return val;
    }
}
//子类,继承父类,并重写lookup()方法
class SubClass extends Base{
    private int num = 10;
    public int lookup(){
        return num;
    }
}
//测试一下
public class Test {
    public static void main(String[] args) {
        SubClass sc = new SubClass();
        System.out.println("sc.value()="+sc.value());
    }
}
打印结果:
sc.value()=0


结果很奇怪,会打印出0,分析了一下,造成原因是这样的:
1.初始化子类对象,会调用子类的构造器,子类的构造器的第一步就是调用父类的构造器,这个是自动隐式的写在了子类构造器的第一行(必须是第一行),原因肯定都知道了,因为子类继承了父类,父类的属性和方法会给子类一些,所以在子类初始化之前,先要保证父类初始化成功了。
2.现在调用到了父类的构造器,父类的构造器会调用lookup()方法
3.问题来了,这里会调用子类的lookup()方法
4.但是子类的num现在还没有初始化,是默认值0(类加载的时候通过内存清0,来实现实例变量的默认初始值),所以打印出0。
这种问题虽然很难碰到,但是如果碰到了,知道怎么回事,可以节省许多时间。

附上类初始化的顺序

引用
引用自: 臧圩人 
   1. 父类--静态变量
   2. 父类--静态初始化块
   3. 子类--静态变量
   4. 子类--静态初始化块
   5. 父类--变量
   6. 父类--初始化块
   7. 父类--构造器
   8. 子类--变量
   9. 子类--初始化块
  10. 子类--构造器
   发表时间:2009-01-15  
构造函数不能调用可被子类复写的方法,构造函数不能创建新线程
前者有可能导致程序初始化不完整,后者可能导致互相等待初始化而死锁
0 请登录后投票
   发表时间:2009-01-16  
此例的执行过程应如下:
     base.Base()  //父类构造方法
    sc.lookup()
    base.value()
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics