日期:2014-05-20  浏览次数:20535 次

core java 2 中是不是出错了?
在core java 2书中有下面一段话:
调用构造器的具体处理步骤:
1、所有数据域被初始化为默认值。
2、按照在类声明中出现的次序依次执行所有域初始化语句和初始化块。
3、如果构造器第一行调用了第二个构造器,则执行第二个构造器主体。
4、执行这个构造器主体。

可是从下面的代码输出结果看却与上面的有些矛盾

 class A {
  private int radius = 10;
  public A()
  {
  draw();
  }
  public void draw()
  {
   
  }
}
class B extends A
{
  private int radius = 1;
  public B()
  {
  }
  public void draw()
  {
  System.out.println(radius);
  }
  public static void main(String[] args)
  {
  B a = new B();
  }
}

输出的结果为:
0

如果按上面的第二条和条三条的顺序来执行的话应该输出1才是啊, 因为在调用第二个构造器之前完成了 “按照在类声明中出现的次序依次执行所有域初始化语句和初始化块。”,那么这时的radius就是1了啊?

大家怎么看呢?

------解决方案--------------------
输出结果是0没错!
基类的构造器先于子类的构造器被调用。
而在基类的构造器内部调用draw(); 根据多态行为,应该调用子类的draw()方法,就是System.out.println(radius);
但此时,由于子类的初始化工作还没进行。radius 也就没有被初始化成1。所以此时输出的是0

------解决方案--------------------
1楼是正解,如果该成下面这样,就有1输出了。
class A { 
private int radius = 10; 
public A() //构造方法

draw(); 

public void draw() 




class B extends A 

private int radius = 1; 
public B() 


public void draw() 
{
System.out.println(radius); 

public static void main(String[] args) 

B a = new B(); 
System.out.println(a.radius);



------解决方案--------------------
程序的入口是main方法,并且main方法是静态的,而private int radius = 10;不是静态的,他必须要在实例化对象以后才被执行。所以我在你那个程序最后加上了System.out.println(a.radius); 意思就是,在前面实例化对象a以后再输出。也可以这样改。在后面加上a.draw();自己去揣摩一下,应该可以理解的。1楼说的很正确:由于子类对象的初始化工作还没进行。radius 也就没有被初始化成1。所以此时输出的是0 。

------解决方案--------------------
2、按照在类声明中出现的次序依次执行所有域初始化语句和初始化块。这个规则是在实例对象的时候遵守的。。。