public class T{
public int i=5;
public T()
{
System.out.println(i);
r();
}
public void r()
{
System.out.println("t");

System.out.println(i);
}
}public class f1 extends T {
public int i=1 public void r()
{

System.out.println("f1");

System.out.println(i);
}
}public class M {
public static void main(String[] args) {

T t=new f1();
t.r();
         System.out.println(t.i);
System.out.println(((f1)t).i);
 
}}结果是5
f1
0
f1
1
5
1是不是先调用父类构造函数,然后打出父类i的值,然后调用子类的r(),可是为何这时子类的i值为0,而父类构照函数中打出的是赋完值的i,成员变量的赋值不是会在类构造过程中就完成了,为何子类方法中会打出的会是子类i初始化的值????还有如果是方法中有调用成员变量的话,是不是默认都是调用子类中定义的,通过父类对象点出来的成员变量,都是父类的值

解决方案 »

  1.   

    类初始化时构造函数调用顺序:
      (1)初始化对象的存储空间为零或null值;
      (2)调用父类构造函数;
      (3)按顺序分别调用类成员变量和实例成员变量的初始化表达式;
      (4)调用本身构造函数。
    这样就比较好解释了,当执行T   t=new   f1(); 时
    1、先是为对象分配空间,这个时候新的f1类的对象,所有字段都是0或是null,也就是说现在对象t中的i的值是0.
    2、调用T的构造函数。在对T构造函数进行调用时,重复上面的的个步骤。因为T直接继承自Object,所以这时:
       1)对T的对象空间进行置0或null操作,这时T中的i也被设置为0了。
       2)调用Object的构造函数
       3) 按顺序对T的变量进行初始化,这时T类中的i被设置成了5
       4)执行T的构造函数本身,先是打印了i的值,为5,然后调用了方法r(),但由于r()被继承,所以这里实际调用的是子类的方法,先是输出f1,然后输出子类中的i的值,可以看到,现在子类中i只进行过了置0的操作,还没有进行赋值操作,所以这时打印的是0.
    3、按顺序对f1的变量进行初始化,这时f1中的i已经被设置成了1
    4、执行f1类的构造函数本身。