java类的加载以及初始化问题总结。

有时候我们编写完代码后,发现运行结构怎么和自己想象的不一样呢?那很有可能就是没有搞清楚类的加载和初始化的过程。下面让我们先看个例子(Thinking in java):

//: c06:Beetle.java
// The full process of initialization.
class Insect {
  private int i = 9;
  protected int j;
  Insect() {
    System.out.println("i = " + i + ", j = " + j);
    j = 39;
  }
  private static int x1 =
    print("static Insect.x1 initialized");
  static int print(String s) {
    System.out.println(s);
    return 47;
  }
}

public class Beetle extends Insect {
  private int k = print("Beetle.k initialized");
  public Beetle() {
    System.out.println("k = " + k);
    System.out.println("j = " + j);
  }
  private static int x2 =
    print("static Beetle.x2 initialized");
  public static void main(String[] args) {
    System.out.println("Beetle constructor");
    Beetle b = new Beetle();
    
  }
} ///:~
本程序的运行结果如下:
 static Insect.x1 initialized
 static Beetle.x2 initialized
 Beetle constructor
 i = 9, j = 0
 Beetle.k initialized
 k = 47
 j = 39
首先当我们运行此程序的时候,主线程启动,编译器开始查找Beetle.class这个类,找到这个类后,开始加载这个类,在加
载的过程发现有extends关键字,所以编译器开始去加载insect.class这个类,(如果在加载这个类的时候如果发现这个类
还有基类,那么insect的直接基类就会被加载,如果还有基类,以此类推)此时因为insect没有基类了,所以不需要再加载,
此时(加载insect类时)insect类的静态代码将执行(静态成员的初始化和静态方法的执行),所以此时打印出了  static 
Insect.x1 initialized, 当insect的静态代码执行完后, Beetle的静态代码开始执行 (初始化x2), 所以打印出:
static Beetle.x2 initialized;到现在为止,所有基类以及静态的初始化动作都已经执行完了,可以创建对象了^_^,
这时候执行System.out.println("Beetle constructor");所以打印出:Beetle constructor,    下面开始执行
 
Beetle b = new Beetle();此时首先为Beetle分配内存空间,并且都初始化为0,注意boolean类型变量初始化为false;
在Beetle内的代码执行前,首先会调用基类的构造器,在基类(insect)的构造器内的代码执行前,首先要执行基类的非静态
成员的初始化,当执行初始化后,基类的构造器里的代码System.out.println("i = " + i + ", j = " + j)开始执行,
所以打印出:i = 9, j = 0;当基类的构造器的代码执行完后,首先要对Beetle类的成员进行显示的初始化,此时K被初始化为
47,并且打印出:Beetle.k initialized;等初始化完成后,Beetle构造器里的代码开始执行,所以打印出:K=47;J=39,
o(∩_∩)o...哈哈程序的结构分析完了。

值得注意的是:静态成员初始化是从最顶层的类开始的,因为子类成员的初始化可能回用到基类的成员。



你可能感兴趣的:(java,.net,J#,asp.net,asp)