public class TestA
{
       TestA()
       {
              System.out.println("P ");
              this.init();
             // System.out.println(this);输出结果竟然是 TestB的引用!不知道为什么????????
       }
       void init()
       {
            System.out.println("Q ");
       }
       public static void main(String[] args)
       {
              TestB testb=new TestB();
       }
}
class TestB extends TestA
{
      int i=1;
      TestB()
      {
             super();
             System.out.println(i+" ");
      }
      void init()
      {
           System.out.println("C ");
           this.i=2;
           System.out.println(i+" ");
      }
}

解决方案 »

  1.   

    http://blog.csdn.net/ZangXT/archive/2009/09/24/4587985.aspx
      

  2.   

    懂了,恍然大悟,因为TestA类的构造方法this.init()中的this是对TestB类对象的引用。
          TestB() 
          { 
                super(); 
                System.out.println(i+" "); 
          } 
    中先执行父类构造方法
          TestA() 
          { 
                  System.out.println("P "); 
                  this.init(); 
                  System.out.println(this); 
          }
    于是,this是对当前对象的引用,而当前对象是TestB的对象,所以this.init()调用TestB类的init()方法。呵呵,希望没有啰嗦!
      

  3.   

    当子类构造函数调用super()时,其只是执行父类构造函数中的语句,其子类自身并没有完成初始化,也就是说子类是初始化的语句并未执行,也就是说子类中init()方法中的i在 int i=1;之前已经执行,所以先输出2,再输出;另外在调用super()执行父类的方法时,其都会检查是否被子类覆盖,this与init()方法都会被子类覆盖,所以其都指向子类中的引用。不知道这样说你明不明白
      

  4.   

    你的TestB继承了父类TestA,在你的main函数中实例他了一个TestB的对象,所以它先执行实例,然后到TestA中的TestA方法,当调用init方法时,由于你的子类中重写了init方法,也就是重载了init方法,此时,init方法则是调用子类TestB中的init()方法!
      

  5.   

    TestA的构造器中这句话:
    System.out.println(this);
    输出的结果是一个地址,其实就是TestB这个实际对象的地址,尽管这里的this是父类TestA引用
      

  6.   

    首先排个版:public class TestA {    TestA() {
            System.out.println("P ");
            this.init();
            // System.out.println(this); 
        }    void init() {
            System.out.println("Q ");
        }    public static void main(String[] args) {
            TestB testb = new TestB();
        }
    }class TestB extends TestA {    int i = 1;    TestB() {
            super();
            System.out.println(i + " ");
        }    void init() {
            System.out.println("C ");
            this.i = 2;
            System.out.println(i + " ");
        }
    } 然后再来分析执行过程:1.main方法中只有一个语句:TestB testb = new TestB();
    看到new TestB()就去找TestB的构造器,得知TestB构造器中第一句话是super();(其实即使不写,super();也是隐式的自动添加到子类TestB构造器中的)2.看到super();顺藤摸瓜,去看父类TestA构造器,里面有两句话:
            System.out.println("P ");
           this.init();
    第一句好说,直接打印:P
    关键在于第二句this.init();
    由于在父类TestA构造器中,所以此处的this是父类TestA的引用,但需要注意的是,虽然引用是父类的,但JVM栈内存中实际的对象是子类TestB的对象,因此,在执行this.init()时,JVM进行动态方法分配(dynamic method dispatch),动态方法分配,简单来说,就是根据实际对象调用相应的方法,因为之前已经解释了,这里的实际对象是子类TestB的对象,所以动态方法分配调用的是子类对象的重写init()方法。3.理解了为什么调用子类TestB的init()方法,再来看方法内部:
            System.out.println("C ");
            this.i = 2;
            System.out.println(i + " ");
    第一句也好说,直接打印:C
    第二句,这里的this.i其实是属于子类对象TestB的父类部分,i暂时被赋值为2
    第三句,打印此时的i值,也就是:24.父类TestA构造器调用完成后,返回到子类TestB构造器中
    这时所做的第一件事情,就是对TestB对象的成员变量赋默认值,因此刚刚在父类构造器中被暂时赋值的i现在被重新赋予一个初始化值1
    接下来执行打印语句:
            System.out.println(i + " ");
    打印结果:1综上所述,完整的代码打印结果为:
    P
    C
    2
    1