在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
分析结果:
- 当调用该类的某个静态方法时,首先加载该类的静态成员变量和静态方法(此时类还没有实例化)
- 当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 variable Loading static variable Loading static method try to new ClassLoadingTest() Loading super class private variable Loading ClassLoadingTestSuper() Loading private variable Loading ClassLoadingTest() Loading NotStaticMethed
分析结果:
- 首先加载的是父类的static变量和方法;
- 然后加载的是该类的static变量和方法;
- 将该类实例化;
- 然后加载的是父类的普通成员变量和方法;
- 然后加载的是父类的构造方法;
- 然后加载的是该类的成员变量和方法;
- 然后加载的才是该类的构造方法;
- 最后实例化结束,外部才可以操作该对象。
得出结论:
当该类有父类的时候,类的实例化的加载过程是:
父类的static成员变量和方法-->该类的static变量和方法-->开始实例化-->父类的普通成员变量和方法-->父类的构造方法-->该类的普通成员变量和方法-->该类的构造方法-->实例化结束。