很简单的一个程序,但是就是想不明白,大牛们来帮下吧~ java编程思想上面的一个练习题。class Component1b { 
  public Component1b(int i) { 
    System.out.println("Component1b " + i); 
  } 

 
class Component2b { 
  public Component2b(int i) { 
    System.out.println("Component2b " + i); 
  } 

 
class Component3b { 
  public Component3b(int i) { 
    System.out.println("Component3b " + i); 
  } 

 
class Rootb { 
 Component1b c1 = new Component1b(1); 
  Component2b c2 = new Component2b(2); 
  Component3b c3 = new Component3b(3); 
  public Rootb() { System.out.println("Rootb1");}
  public Rootb(int i) { System.out.println("Rootb2"); } 

 
class Stemb extends Rootb { 
  
  Component1b c1 = new Component1b(4); 
  Component2b c2 = new Component2b(5); 
  Component3b c3 = new Component3b(6); 
 
  public Stemb(int i) { 
  super(i);
    System.out.println("Stemb"); 
    
  } 

 
public class test { 
  public static void main(String args[]) { 

    new Stemb(47); 
    
  } 
}程序的输出结果如下:
Component1b 1
Component2b 2
Component3b 3
Rootb2
Component1b 4
Component2b 5
Component3b 6
Stemb我有个地方想不明白。按照正常的初始化顺序应该是先初始化变量和对象,然后才是构造器方法。得出的结果应该是
Component1b 1
Component2b 2
Component3b 3
Rootb2
Component1b 4
Component2b 5
Component3b 6
Rootb2
Stemb倒数第二行的结果没有出现,super(i)自动被忽略了。  我设置了断点之后 发现执行过程是这样的:程序首先跳到子类的构造函数中找到super(i),然后才初始化基类成员变量,基类对象。然后初始化子类成员变量,执行子类构造函数。在执行子类构造函数的时候,自动跳过了super(i)这一父类构造函数。  这一点和我上面提到的正常初始化顺序又有矛盾了。如果是这样的话 子类的成员变量应该优先被初始化才对。
大牛们 谁能帮我解答下疑惑。是不是,在涉及到新建子类是,java默认设定的规则就是先到子类的构造函数中寻找合适的父类构造方法,然后按照正常的顺序初始化父类成员变量,执行父类构造方法,初始化子类成员变量,执行子类构造函数。而最重要的一点,子类构造函数中父类的构造方法在这时候不会执行??谢谢啦

解决方案 »

  1.   

    如果跳过了super(i)那你中间那行 Rootb2 是哪来的……
      

  2.   

    那 super(i)是啥时候执行的。这个程序应该是先到子类的构造方法里面找到super(i),但是没有立即执行。而是在初始化父类的成员变量之后才执行的。对吧。我就说想问这个地方。
      

  3.   

    很好理解啊,首先初始化基类的成员变量,然后调用super(i),就是public Rootb(int i) { System.out.println("Rootb2"); }  这个方法,然后在System.out.println("Stemb"); 之前又会初始化子类的成员变量,这时super(i)已经执行过了,当然不会再执行了,之后再执行System.out.println("Stemb");
    }  
      

  4.   

    学习学习。
    class Component1b {  
        public Component1b(int i) {  
          System.out.println("Component1b " + i);  
        }  
    }  
      
    class Component2b {  
        public Component2b(int i) {  
            System.out.println("Component2b " + i);  
        }  
    }  
      
    class Component3b {  
        public Component3b(int i) {  
            System.out.println("Component3b " + i);  
        }  
    }  
      
    class Rootb {  
        Component1b c1 = new Component1b(1);  
        Component2b c2 = new Component2b(2);  
        Component3b c3 = new Component3b(3);    public Rootb() { 
            System.out.println("Rootb1");
        }    public Rootb(int i) { 
            System.out.println("Rootb2"); 
        }  
    }  
      
    class Stemb extends Rootb {  
      
        Component1b c1 = new Component1b(4);  
        Component2b c2 = new Component2b(5);  
        Component3b c3 = new Component3b(6);  
      
        public Stemb(int i) { 
            super(i);
            System.out.println("Stemb");  
        }  
    }  
      
    public class test {      public static void main(String args[]) {  
            new Stemb(47);  
        }  
    }
      

  5.   


    大概是这样的 但是用设下断点 你会发现程序一开始不是先初始化基类的成员变量,而是先跑到子类的构造函数里面去找一下super(i),然后再初始化基类的成员变量。我的意思是这样的:是不是每次新建一个子类对象的时候,跑到子类构造函数里面去找一下父类的构造函数这一个动作是最开始的?
      

  6.   

    对,new 子类构造时,在子类构造的第一行默认是super()父类构造的,你要是写了super()父类构造,那个默认的就消失了。当然还有另外一种情况,在子类的构造中第一行this()调同类的另外一个构造,另外那个构造的第一行会调super()。
    ===========================
    因为,在一个构造中的第一行只有三种情况
    第一种:缺省(就是默认)super父类构造
    第二种:你写了super父类构造(此时缺省的super就消失了)
    第三种:你写了this(此时缺省的super也消失了)
    父类构造执行完了,才返回来执行,子类构造的第2行。
    因此,你每new一个类时,这个类都会执行父类构造,Object是所有类的父类,其他不多说,应该明白了吧
    new 孩子(),第一行super父类
    父类的第一行会new Object,Object构造执行完毕后,返回 父类构造的第二行,父类构造执行完毕后,执行孩子构造的第二行。
      

  7.   

    原来还有new object这一过程啊 以前还真不知道...受教了 thx。。
      

  8.   

    表述有误,不是new Object而是super()调用Object的构造。因为Object是所有类的父类。