class Bowl{
 Bowl(int er){
  System.out.println("Bowl("+er+")");
 }
 void f(int er){
  System.out.println("f("+er+")");
 }
}class Table{
 static Bowl b1=new Bowl(1);
 Table(){
  System.out.println("Table()");
  b2.f(1);
 }
 void f2(int er){
  System.out.println("f2("+er+")");
 }
 static Bowl b2=new Bowl(2);
}class Cupboard{
 Bowl b3=new Bowl(3);
 static Bowl b4=new Bowl(4);
 Cupboard(){
  System.out.println("Cupboard()");
  b4.f(2);
 }
 void f3(int er){
  System.out.println("f3("+er+")");
 }
 static Bowl b5=new Bowl(5);
}public class StaticInitialization{
 public static void main(String[] args){
  System.out.println("Creatin new Cupboard() in main");
                                                  //================================================                            
  new Cupboard();===========================>>>>>||为什么这里NEW出来还会去调用Bowl bowl=new Bowl(3)
                                                 ||应该去调用Cupboard这个类的Cupboard()方法.

                                                  \\===============================================
  System.out.println("Creatin new Cupboard() in main");
  new Cupboard();
  t1.f2(1);
  c1.f3(1); }
 static Table t1=new Table();
 static Cupboard c1=new Cupboard();
 
}

解决方案 »

  1.   

    因为在调用Constructor的之前必须保证初始化都做完
      

  2.   

    java中在调用Constructor的之前必须保证初始化都做完
      

  3.   

    楼主的代码是TIJ里的吧,以前看的,忘了。涉及初始化问题,全世界就TIJ这本书讲的最牛。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结合就行了。
      

  4.   

    但是在MAIN里不是有这个static Cupboard c1=new Cupboard()静态构造方法.(TABLE先不考虑).
    先会调用这个构造方法..会去Cupboard类里找new Cupboard()的构造方法,首先会执行static Bowl b4=new Bowl(4)还有static Bowl b5=new Bowl(5);然后去执行 Bowl b3=new Bowl(3)(这就是楼上所说的调用构造方法前.必须保证初始化都做完)然后就是构造方法了
    但是这个程序又来了一次new Cupboard(),在这次前面不是已经把Bowl b3=new Bowl(3)已经初始化了..
    (难道就因为他没个STATIC(是不是 不是STATIC的.每次调用构造方法多要初始化)但是构造方法也可以认为是个静态方法)深深的困扰我....
      

  5.   


    楼主可以把static Cupboard c1=new Cupboard()这句话移到Bow1方法中的第一句中运行一下,你就全明白了
    初始化是按类来分,从上往下一个类一个类的开始初始化,并不是从public类开始。
      

  6.   


    怎么讲呢,感觉TJI把你困惑住了,呵呵。先看下new Cupboard();这句语句跟平常我们创建对象的语句相同,只是没有引用指向它,换句话说就是这个对象被创建出来后就成为垃圾对象(当内存要崩溃时,垃圾收集器会来处理它的)你说的这个程序又来一次???这句话是什么意思???在程序里如果你想要那么你创建几个对象或是想new几次都行呀!!!new Cupboard();跟Bowl b3 = new Bowl(3);这两者只是分别创建对象,不相关呀!!!不知道我是否没有理解读者所问的意思,如果我理解错了,那真的不好意思,呵呵...
      

  7.   


    public static void main(String[] args){
      System.out.println("Creatin new Cupboard() in main");                        
      new Cupboard();
            ||             
     ==========================================================================                                      
     楼上我所说的程序又来一次new Cupboard()                                       
    static Cupboard c1=new Cupboard()然后会来执行
    这个 new Cupboard(); 他跟Bowl b3 = new Bowl(3)是                    
    不相关的..只是分别创建对象的(不过1楼已经说过调用构造方法前
    必须保证初始化都做完
    ,但问题是我们先会去执行static Cupboard c1=new
     Cupboard()会去初始化Bowl b3 = new Bowl(3) 我们在new Cupboard(),为什么还
    会去Bowl b3 = new Bowl(3)(他不是已经初始化了))
    ============================================================================                                                    
      System.out.println("Creatin new Cupboard() in main");
      new Cupboard();
      t1.f2(1);
      c1.f3(1);}
    static Table t1=new Table();
    static Cupboard c1=new Cupboard();
      

  8.   

    ==========================================================================                                     
    楼上我所说的程序又来一次 是指这的new Cupboard()                                     
    可是程序会执行static Cupboard c1=new Cupboard()然后会来执行这个 new Cupboard();
    他跟Bowl b3 = new Bowl(3)是不相关的..只是分别创建对象的(不过1楼已经说过调用构造
    方法前必须保证初始化都做完,但问题是我们先会去执行static Cupboard c1=new
    Cupboard()会去初始化Bowl b3 = new Bowl(3) 我们在new Cupboard(),为什么还
    会去Bowl b3 = new Bowl(3)(他不是已经初始化了))
    ============================================================================刚才逻辑不是很好.重发下
      

  9.   

    搞得有点跟不上LZ在说什么了
    这个是TIJ上的例子
    好好看看书就能理解了
      

  10.   

    我在看.就是不是很明白.
    我们会因为static Cupboard c1=new Cupboard()会初始化Bowl b3 = new Bowl(3)
    但是在再又new Cupboard()后,还要初始化Bowl b3 = new Bowl(3)吗??