1,java类的加载机制
系统类加载器(system class loader)
Ⅱ
Ⅴ
扩展类加载器(extensions class loader)
Ⅱ
Ⅴ
引导类加载器(bootstrap class loader)
除了引导类加载器之外,所有的类加载器都有一个父类加载器。通过给出的 getParent()方法可以得到。对于系统提供的类加载器来说,系统类加载器的父类加载器是扩展类加载器,而扩展类加载器的父类加载器是引导类加载器;对于开发人员编写的类加载器来说,其父类加载器是加载此类加载器 Java 类的类加载器。因为类加载器 Java类如同其它的 Java 类一样,也是要由类加载器来加载的。一般来说,开发人员编写的类加载器的父类加载器是系统类加载器。类加载器通过这种方式组织起来,形成树状结构。树的根节点就是引导类加载器。
2,java类加载的先后顺序
父类的静态方法2
父类静态初始化块
子类静态初始化块
父类非静态初始化块
父类的构造方法
子类非静态初始化块
子类的构造方法
Parent类:
package ClassLoadOrder; /* * 1,虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化; * (类中static成员按在类中出现的顺序加载) * * 2,只有在调用new方法时才会创建类的实例; * * 3,类实例创建过程:按照父子继承关系进行初始化, * 首先执行父类的静态初始化块、静态成员变量、静态方法块部分; * 在执行子类的静态初始化、静态成员变量、静态方法块部分; * 然后是父类的非静态初始化块(一对大括弧中),接着是父类的构造方法; * 最后执行本类继承的子类的非静态初始化块,接着是子类的构造方法; */ public class Parent { public Parent() { System.out.println("父类的构造方法"); } { System.out.println("父类非静态初始化块"); } static { System.out.println("父类静态初始化块"); } public static int t = parentStaticMethod2(); public static int parentStaticMethod() { System.out.println("父类类的静态方法"); return 10; } public static int parentStaticMethod2() { System.out.println("父类的静态方法2"); return 9; } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub super.finalize(); System.out.println("销毁父类"); } }
Child类:
package ClassLoadOrder; public class Child extends Parent { { System.out.println("子类非静态初始化块"); } static { System.out.println("子类静态初始化块"); } public Child() { System.out.println("子类的构造方法"); } public static int childStaticMethod() { System.out.println("子类的静态方法"); return 1000; } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub super.finalize(); System.out.println("销毁子类"); } }
Test类:
package ClassLoadOrder; public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub /*Parent.parentStaticMethod(); System.out.println(); Parent.parentStaticMethod2(); System.out.println(); Parent.parentStaticMethod();*/ Child child = new Child(); //child.childStaticMethod(); //Parent parent = new Parent(); } }
运行得到以下的结果:
父类静态初始化块 父类的静态方法2 子类静态初始化块 父类非静态初始化块 父类的构造方法 子类非静态初始化块 子类的构造方法
总结:
1,虚拟机在首次加载Java类时,会对静态初始化块、静态成员变量、静态方法进行一次初始化;
(类中static成员按在类中出现的顺序加载)
2,只有在调用new方法时才会创建类的实例;
3,类实例创建过程:按照父子继承关系进行初始化,
首先执行父类的静态初始化块、静态成员变量、静态方法块部分(静态成员执行按照代码的先后顺序执行);
在执行子类的静态初始化、静态成员变量、静态方法块部分(静态成员执行按照代码的先后顺序执行);
然后是父类的非静态初始化块(一对大括弧中),接着是父类的构造方法;
最后执行本类继承的子类的非静态初始化块,接着是子类的构造方法;