请教高手个问题,很关键,怎么也没想明白,先谢谢啦
public class Test extends TT {
public static void main(String[] args) {
Test R=new Test("Tom");
}
public Test(){
System.out.println("I am tom");
}
public Test(String s){
super(s);
System.out.println("How are you?");
}
}public class TT {
public TT(){
System.out.println("What's a pleasure!");
}
public TT(String s){
this();
System.out.println("I am "+s);
}
}结果:
What's a pleasure!
I am Tom
How are you?首先调用TT的含参构造方法,执行里面的this后,后面的System.out.println("How are you?");不执行吗?
在随后的super调用父类(TT)的含参构造方法时,怎么没有执行TT.TT()啦?

解决方案 »

  1.   

    你main里面是Test(“Tom”);所以会到public Test(String s),而这里有个super(s),所以会到public TT(String s),这里有个this(),所以回到public TT()---构造器调用用this关键字,所以顺序就是这样子
      

  2.   

    我具体说下我的思路:
    首先由于new了Test,所以就应该先调用父类的含参构造方法,在父类含参构造方法中由于有this();那么调用不含参的构造方法,输出what's a pleasure!,然后之下那个输出I am Tom.继续执行Test含参的构造方法,由于Test含参构造方法有super方法,那么就会父类的含参构造方法,应该再次执行this(),然后输出I am Tom.最后执行输出Test类里的How are you?请教一下这个思路有什么问题吗?
    如果按我的思路结果应该是:
    What's a pleasure! 
    I am Tom 
    What's a pleasure! 
    I am Tom 
    How are you? 
    麻烦高手解释下,谢谢
      

  3.   

    如果类中显示声明了含参构造函数,当你new出这个对象时,Object o = new Object(String s);此时就会执行
    含参的那个构造函数;如果想执行默认构造函数,需要显示使用this();语句,否则的话,默认构造函数不会执行。
      

  4.   

    能具体说一下,执行顺序吗?super(s);和直接new不都只在执行含参构造方法为什么一个执行this(),super调用不执行啊?
      

  5.   

    JAVA有一点跟C++不一样,JAVA语法中没有“父类及成员的初始化列表”,因此,没有一种额外设计的语法来明确指定通过父类的哪个构造函数来构造父类子对象。
    既然没有“额外的语法”,那构造函数的第一句便有了非比寻常的特殊含义,如果构造函数的第一句是super(...),那就表示显式地指明调用父类的特定构造函数来初始化父类子对象,这样,父类的默认构造函数便不再被自动调用。相反,如果第一句不是super(...),编译器则会帮我们自动调用父类的默认构造函数来完成父类子对象的初始化。
    也正是因为这个原因,如果你要在一个子类的构造函数中通过super(...)来显式指定父类的某个特定构造函数,那么它必需作为这个构造函数第一条语句。
      

  6.   

    明白楼主的意思了,但是要知道,构造方法是用来创建对象的。
    如果有继承(实际上除了Object类),在本类构造方法的最开始要调用父类的构造方法,这是必须的,但只会调用一次(前面说了,构造方法是为了创建对象的,调二次就不对了),如果你自己在本类的构造方法中没有明白的调用父类的构造方法,系统会自动为你调用父类的那个无参构造方法,但如果你自己主动调用了父类的构造方法了,系统就不会给你自动调用了。只调用一次。不知道楼主明白了没有。
      

  7.   

    谢谢高手的指教,我们上课还真没说过构造方法有super的时候就不再调用父类构造方法,现在我明白怎么回事了。十分感谢
      

  8.   

    我理解所谓先执行父类的构造方法,
    是指在子类构造方法里不调用父类的构造方法时,
    在构造方法执行的最初执行父类的不带参的构造方法;(证明:在eclipse自动生成不带参构造器时,都有一句super();)
    但如果子类构造器指明了调用父类的带参构造器的情况下执行顺序

    父带参构造器-》子构造器
    本例父不带参构造器-》父带参构造器-》子构造器
      

  9.   

    super()是继承父类的构造方法
    会先背执行
      

  10.   

    public static void main(String[] args) { 
    Test R=new Test("Tom"); 

    public Test(){ 
    System.out.println("I am tom"); 

    public Test(String s){ 
    //super(s); 
    System.out.println("How are you?"); 

    }  class TT { 
    public TT(){ 
    System.out.println("What's a pleasure!"); 

    public TT(String s){ 
    this(); 
    System.out.println("I am "+s); 


    结果是 What's a pleasure!
    How are you?为什么调用父类 this 后面那句话不被执行呢   要有super 才会被执行
      

  11.   

    回复 20  楼因为程序在执行public Test(String s) 构造函数的时候会默认调用无参的父类构造函数:super() (前提是该方法中没有人为的调用super)  所以程序会先去执行父类的无参的构造函数public TT(),而不会去执行父类中的public TT(String s)构造函数
      

  12.   

    是由于继承,在执行构造方法时先执行父类构造方法
    执行顺序:调用Test带参构造方法Test(String s),方法里先执行父类构造方法,调用TT的带参构造方法
    TT(String s)
      

  13.   

    谢谢你的回答 可是我还是不明白
    先去执行父类的无参的构造函数public TT(),而不会去执行父类中的public TT(String s)构造函数
    那用了super 后不是还要在执行一次public TT(String s)吗?
    那结果不就是 
    What's a pleasure! 
    How are you? 
    What's a pleasure! 
    I am Tom 
    How are you? 
      

  14.   

    不能说构造函数是创建对象,这样说其实是不太严谨的,在这里我不想细说。
    构造函数的第一句如果不是super就是this,因为构造函数的开始一定是从另外一个构造函数开始的,而这个构造函数可以是自己本身的某个构造函数,也可以是父类的构造函数,如果没有显示的调用super与this关键字调用父类或者本类的构造函数,则默认为super()开始。
      

  15.   

    你要是看过关于继承方面的东西就好了,我给你解释下,
    (1)在执行的时候会先去找main方法,
    发现main在Test类中,而Test类继承了 TT 类,所以,就先调用了TT类的无参数构造方法
    public TT(){ 
    System.out.println("What's a pleasure!"); 
    } 打印出What's a pleasure!(2)然后你实例化了Test 类的有参数构造函数,在这个构造函数中
    super(s); 是调用了父类的有参构造函数
    public TT(String s){ 
    this(); 
    System.out.println("I am "+s); 
    } 打印出I am Tom
    (3) 调用完父类的了,按照调用顺序,该执行有参数构造函数的下一句
    打印出How are you? 就是这个按照这个顺序执行的。所以才会出现这个结果。
      

  16.   

    this()没执行,是因为无参构造函数已经初始化过了,所以没有执行。
      

  17.   

    Test R=new Test("Tom"); 
    这里一开始就跑
    Test(String s)  {
    super(s);//这里指向了父类的相同的构造
    System.out.println("How are you?");
    }public TT(String s){ 
    this();//这里指向了自己的默认构造器
    System.out.println("I am "+s); 

    public TT() {
    System.out.println("What's a pleasure!"); 
    }所以先打印System.out.println("What's a pleasure!"); 
    在System.out.println("I am "+s); 
    构造器
    最后System.out.println("How are you?");
      

  18.   


    class TT {
    /*
     * --------------不带参数的构造函数----------------------
     */
    public TT() {
    System.out.println("What's a pleasure!");
    // System.out.println("12312");
    }
    /*
     * 带参数的构造函数
     * 这里面的this()就好像调用了TT()不带参数
     * 的构造函数一样所以上面的不带参数
     * 的构造函数就会被执行
     */
    public TT(String s) {
    this();
    System.out.println("I am " + s);
    }

    class Test extends TT {
    /*
     * 这里面如果没有参数就会执行TT()里面的数据
     * 如果底下有数据它不但要执行TT()不带参数的构造函数里面的数据
     * 还要执行这个Test里面的数据
     */
    public Test() {
    System.out.println("I am tom");
    }
    /*
     * 这里是继承了上面的TT()带参数的构造函数了。
     * 因为super(s)
     * 所以自然而然就执行了上面的TT(String s)里面的
     * 内容了。
     */
    public Test(String s) {
    super(s);
    System.out.println("How are you?");
    }
    public static void main(String[] args) {
    Test R = new Test("Tom"); Test t = new Test();
    }
    }
      

  19.   

    this() 调用的是本类的构造方法,super()调用的是父类的构造方法,设置断点运行下就会明白的。
      

  20.   

    构造函数如果什么都不写会自动调用super()的,如果写了就会调用指定的super(**)/this(**)....还是没明白楼主的逻辑是咋回事
      

  21.   

    this() 调用的是本类的构造方法,super()调用的是父类的构造方法:Test R=new Test("Tom");
    程序首先调用 -->public Test(String s)-->遇到(super(s))就调用父类一个参数的构造方法-->public TT(String s)--->遇到this(): 调用的是本类的构造方法(输出What's a pleasure)-->
    然后再输出(I am "+s") -->最后回到public Test(String s)执行  System.out.println("How are you?");语句所以答案: