2007.06.12

3、 类的初始化.

    对某个类运行Java时,发生的第一件事就是装载程序到外面找到该类,将该

类装载入内存.在装载过程中,会发生两种情况:

(1)    如果该类没有父类.则

    a、首先装载static(静态初始化),因为该类的所有对象共享一个static变

量(方法),而不同的对象分配不同的内存,所以先静态初始化.

    b、接下来是类的(非静态)初始化语句(变量的初始化),

    c、最后到构造函数.

       如果该类有父类,则较为麻烦,顺序如下:

a、父类静态初始化,子类静态初始化;

b、父类非静态初始化, 父类构造函数;

c、子类非静态初始化,子类构造函数.

如果发现父类还有父类,则以此类推.

用下图能比较清晰的了解:


java类半初始化并发_java



示例如下

: 
 
   
 
 
 
  package ex;

 
  class 
   Insert

 
  ... 
  {
  int i=9;//2.1 非静态初始化
  int j;  //2.2  同上
  
  
    
  Insert()//2.3 构造函数
  ...{
      prt("i="+i+",j="+j);
      j=39;
  }

  static int x1=prt("static insert x1 initialized");//1.1 静态

  static int prt(String s)
  ...{
       System.out.println(s);
       return 47;
  }
} 
  

 
  public 
    
  class 
   Beetle extends Insert
 
  ... 
  {
     int k=prt("Beetle.k initialized");//3.1 非静态初始化

     Beetle()//3.2
     ...{

     prt("k="+k); //3.2.1

     prt("j="+j); //3.2.2

     }

 static int x2=prt("static Beetle.x2 intialized");//1.2 静态

     static int prt(String s)

     ...{

     System.out.println(s);

     return 63;

     }

     public static void main(String[] args)

     ...{

     prt("Beetle constructer");//1.3

     Beetle x = new Beetle();

     }

} 
  
 

执行结果如下:

 
 
   
static    insert x1 initialized

   static 
   Beetle.x2 initialized

Beetle constructer

i   = 
  9 
  ,j 
  = 
  0 
  

Beetle.k initialized

k   = 
  63 
  

j   = 
  39

    上面这个例子还包括了一个子类一个父类,相对初始化装载的时候稍微有点麻

烦一点,但是总体原则是一样的。根据上面的编号,装载的顺序是:

    1.1,1.2,1.3,,2.1,2.2,2.3,3.1,3.2。

    当在装载Beetle类的时候,先去找Beetle.class把他装载进来,在

Beetle.class装载到一半的时候,发现他还有个父类 Insect.class,那么需

要把Insect.class也装载进来,并且先对他进行初始化,那么1.1是最先被初始

化的,接下来父类装载完毕之后,子类接着也装载进来,这样,1.2接着被初始化。

new Beetle()的时候,先分配内存,接着父类的非静态初始化,然后父类构造函

数,所以2.*陆续初始化,接着是子类3.*

    基本上初始化的顺序是先父类后子类,先静态,后非静态,最后才是构造函数。