你的位置:首页 > Java教程

[Java教程]类和对象的加载过程


  在Java中,

  当一个类被调用的时候,它的加载过程是怎么样的呢?

  当一个类被实例化的时候,它的加载过程又是怎样的呢?

  为什么static方法不能未经对象就调用非static方法?

  下面我们通过例子来找出答案。

 

当该类没有父类时

  测试代码:  

public class ClassLoadingTest {  static String staticString=getStaticString();  //静态成员变量  private String privateString=getPrivateString();//普通成员变量  public ClassLoadingTest() {    System.out.println("Loading ClassLoadingTest()");  }  public static void loadStaticMethod() {    System.out.println("Loading static method");  }    private void loadNotStaticMethed(){    System.out.println("Loading NotStaticMethed");  }    private String getPrivateString() {    String string=new String("Loading private variable");    System.out.println(string);    return string;  }  private static String getStaticString() {    String string=new String("Loading static variable");    System.out.println(string);    return string;  }    public static void main(String[] args) {    loadStaticMethod();  //加载静态方法    System.out.println("try to new ClassLoadingTest()");    ClassLoadingTest test=new ClassLoadingTest();    test.loadNotStaticMethed();//加载普通方法  }}

   打印结果:  

   Loading static variable   Loading static method   try to new ClassLoadingTest()   Loading private variable   Loading ClassLoadingTest()   Loading NotStaticMethed     

 

  分析结果:

    1. 当调用该类的某个静态方法时,首先加载该类的静态成员变量和静态方法(此时类还没有实例化)
    2. 当new该类之后,会加载该类的普通成员变量,然后才是构造方法。

  得出结论:

    当一个类没有父类的时候,加载顺序为:

    静态成员变量/静态方法-->开始实例化-->普通成员变量/普通方法-->构造方法-->实例化结束。

 

当该类有父类的时:

  测试代码:

    父类:

public class ClassLoadingTestSuper {  static String staticString=getSuperStaticString();    //父类的静态成员变量  private String privateString=getSuperPrivateString();  //父类的普通成员变量  public ClassLoadingTestSuper() {    System.out.println("Loading ClassLoadingTestSuper()");  }    private String getSuperPrivateString() {    String string=new String("Loading super class private variable");    System.out.println(string);    return string;  }  private static String getSuperStaticString() {    String string=new String("Loading super class static variable");    System.out.println(string);    return string;  }}

    子类:

public class ClassLoadingTest extends ClassLoadingTestSuper {/*内容与ClassLoadingTest相同*/}

  打印结果:

Loading super class static variableLoading static variableLoading static methodtry to new ClassLoadingTest()Loading super class private variableLoading ClassLoadingTestSuper()Loading private variableLoading ClassLoadingTest()Loading NotStaticMethed

  分析结果:

    1. 首先加载的是父类的static变量和方法;
    2. 然后加载的是该类的static变量和方法;
    3. 将该类实例化;
    4. 然后加载的是父类的普通成员变量和方法;
    5. 然后加载的是父类的构造方法;
    6. 然后加载的是该类的成员变量和方法;
    7. 然后加载的才是该类的构造方法;
    8. 最后实例化结束,外部才可以操作该对象。

 

  得出结论:

    当该类有父类的时候,类的实例化的加载过程是:

      父类的static成员变量和方法-->该类的static变量和方法-->开始实例化-->父类的普通成员变量和方法-->父类的构造方法-->该类的普通成员变量和方法-->该类的构造方法-->实例化结束。