java底层:类的加载机制,类的加载先后顺序

1,java类的加载机制


系统类加载器(system class loader)
              Ⅱ
     Ⅴ
扩展类加载器(extensions class loader)
     Ⅱ
     Ⅴ
引导类加载器(bootstrap class loader)
     

java底层:类的加载机制,类的加载先后顺序_第1张图片


除了引导类加载器之外,所有的类加载器都有一个父类加载器。通过给出的 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,类实例创建过程:按照父子继承关系进行初始化,
      首先执行父类的静态初始化块、静态成员变量、静态方法块部分(静态成员执行按照代码的先后顺序执行);
      在执行子类的静态初始化、静态成员变量、静态方法块部分(静态成员执行按照代码的先后顺序执行);
                                    然后是父类的非静态初始化块(一对大括弧中),接着是父类的构造方法;
                                    最后执行本类继承的子类的非静态初始化块,接着是子类的构造方法;

你可能感兴趣的:(java基础,java类加载机制,java类加载的先后顺序)