JVM:class加载时机及两种显示加载的区别

转载请注明出处:jiq•钦's technical Blog


从下面代码可以看出来几点:


1、 class文件的加载的时机

显示加载:

         调用ClassLoader.loadClass(className)与Class.forName(className)

隐式加载:

         创建类对象

         使用类的静态域

         创建子类对象

         使用子类的静态域

注意其实还有其他特殊的隐式加载:

在JVM启动时,BootStrapLoader会加载一些JVM自身运行所需的class

在JVM启动时,ExtClassLoader会加载指定目录下一些特殊的class

在JVM启动时,AppClassLoader会加载classpath路径下的class,以及main函数所在的类的class文件。

 

2、 两种显示加载class文件到JVM的区别

Class.forName(className)加载class的同时会初始化静态域

ClassLoader.loadClass(className)则不会初始化静态域

Class.forName借助当前调用者的class的ClassLoader完成class的加载。

 

3、 class文件的隐式加载会执行static域 

4、 JVM默认的ClassLoader是AppClassLoader 

=================================== 下面附上测试代码 =========================================

package jiq.basic;

class SuperClass
{
	public static int i = 0;
	public static void func(){}
	static {System.out.println("静态区域被执行!");}
}

class SubClass extends SuperClass
{
	public static int j = 0;
}

public class Test 
{
	//仅仅只是作为参数或者变量出现不会载入对应的class文件
	SuperClass cc1 = null;
	
	public static void TestClassLoader(SuperClass vv) throws ClassNotFoundException
	{
		/**
		 * 显示载入class并初始化静态域
		 * 将打印:静态区域被执行!
		 */
		Class.forName("jiq.basic.SuperClass");
		
		/**
		 * 隐式载入class并初始化静态域
		 * 将打印:静态区域被执行!
		 */
		SuperClass c = new SuperClass();	//使用关键字new创建对象
		SuperClass.i = 9;	//使用类的静态字段
		SuperClass.func(); //使用类的静态方法
		new SubClass();	//使用关键字new创建子类对象
		SubClass.j = 10; //使用子类的静态域
		
		/**
		 * 仅仅只是作为参数或者变量出现不会载入对应的class文件
		 * 不会打印:静态区域被执行!
		 */
		SuperClass cc = vv;
		SuperClass array[] = new SuperClass[5];
		
		/**
		 * 调用ClassLoader的loadClass方法只会加载class文件到JVM
		 * 并不会初始化静态区域,这就是ClassLoader.loadClass与Class.forName的区别
		 * 不会打印:静态区域被执行!
		 */
		ClassLoader.getSystemClassLoader().loadClass("jiq.basic.SuperClass");
				
		/**
		 * 输出为sun.misc.Launcher$AppClassLoader@2d74e4b3
		 * 可以看出JVM默认的类加载器ClassLoader是AppClassLoader
		 * 而BootStrapClassLoader和ExtClassLoader都是相对较为特殊的ClassLoader
		 */
		System.out.println(ClassLoader.getSystemClassLoader());
	}
	
	public static void main(String[] args) throws ClassNotFoundException 
	{
		TestClassLoader(null);
	}

}


你可能感兴趣的:(Java)