class Tag {
  Tag(int er) {
    System.out.println("Tag(" + er + ")");
  }
}class Card {
  Tag t1 = new Tag(1); // Before constructor
  Card() {
    // Indicate we're in the constructor:
    System.out.println("Card()");
    t3 = new Tag(33); // Reinitialize t3
  }
  Tag t2 = new Tag(2); // After constructor
  Tag t3 = new Tag(3); // At end
}public class OrderOfInitialization {
  public static void main(String[] args) {
    Card t = new Card();
    
  }  Tag t4=new Tag(4);
  static Tag t5=new Tag(5);
   
} ///:~这个程序的输出结果是
Tag(5)
Tag(1)
Tag(2)
Tag(3)
Card()
Tag(33)————————————————
为什么主class中的field: Tag t4=new Tag(4)不会执行到呢?不是按照先field再method的顺序执行的吗?
谢谢。

解决方案 »

  1.   

    这个问题很简单,因为t4不是静态成员注意,非静态成员只有在创建该类对象的时候才会进行初始化而t5是静态成员,它在你装载主class的时候(访问主类的main方法时)就进行初始化了,所以是第一个其它的就不解释了你在main里加上语句new OrderOfInitialization();试试,T4就出来了
      

  2.   

    回答过类似的问题,直接复制给你java编译器确保域(成员变量或块)在被使用之前必需初始化,即使你没直接初始化,它也会默认给你一个值。1.
      如果不涉及继承跟static,用new创建对象时,会调用那个类的构造函数,而在调用构造函数之前必需先初始化域(因为在构造函数里,可能会用到这些成员变量)
    等域初始化完后再调用构造函数。强调一点:只要是成员变量,那么不管它放在类的哪个部位(但在方法或块内部不算,因为那算是局部变量),它都在构造函数调用之前调用,这是编译器确保的。2.
    如果涉及继承,当用new创建子类对象时,调用顺序是这样的:
      1.先初始化父类的域(成员变量或块)
      2.调用父类的构造函数(没有明确定义的话,调用默认那个,即编译器为你创建的)
      3.再到子类,初始化子类的域
      4.这时才轮到调用子类的构造函数
    原则是:要确保域在被调用之前要被初始化.
    上面是涉及两层,如果是涉及多层继承的,那么一致递推上去,即先初始化父类的域,然后调用父类构造函数,再初始化子类的域然后再调用子类的构造函数,再初始化子子类的域(用这个名字好像有点怪,哈哈,就是孙子类的意思)然后再调用子子类的构造函数,一致类推下去
    3.涉及static的话,static域是在编译的时候加载的,原则是:
      1.static域是在非static(上面说的都是非static)之前调用的
      2.static域只初始化一次(即只调用一次),打个比方A a = new A(); A 里有static域,只有当你第一次使用new创建对象的时候它会在非static之前调用,而如果你还想再用new创建对象时,static域这段代码是不会被调用的(因为static的东西是属于类,所以对象共享的,一次就够了)4.如果涉及继承跟static结合的话(而这个是初始化里最难的,很多初学者会卡在这里),只要按照3.2结合就行了。 
      

  3.   

    think in java里初始化和清除那一章讲得很清楚如果你不想翻书,不妨看看我的blog
    http://blog.csdn.net/icesnows/archive/2009/05/24/4211810.aspx
    里面有这些内容: static成员初始化在non-static初始化之前(后者只在创建该类对象时才进行初始化)。参见例StaticInitialiaztion。     所以,初始化的顺序应该是这样的:     1. static自动初始化;2. static specifying initialization;3. non-static 自动初始化;4. non-static specifying initialization;5. 构造器初始化     创建对象的过程:     1. 定位class;2. 装载class,static初始化(仅此一次);3. 在heap中分配对象内存;4. 对象内存清0,即完成自动初始化;5. specifying initialization,即赋给变量定义时指定的初值;6. 执行构造器(如果有继承就更复杂)
      

  4.   

    经过上述几位的指点,终于明白了。本来我一直困惑:为什么Card类中非静态field (Tag t1)能执行,而主class的非静态field (Tag t4)不能执行呢?原来关键是:
    非静态成员只有在创建该类对象的时候才会进行初始化。
      

  5.   

    OrderOfInitialization没有创建实例, Tag t4=new Tag(4); 是成员变量, 只有创建OrderOfInitialization实例时才创建.