classLoader加载class的流程

以下是针对sun的hotspot,当然现在sun已被oracle收购

Java在需要使用类的时候才会将其载入,Java的类载入是由Classloader来执行的。

现在以win下执行java xxx来讲解下流程:

  1. 首先java执行文件会尝试找到JRE安装的所在目录,然后寻找jvm.dll(预设是在JRE目录下bin\client目录中,比如C:\Java\jdk1.7.0_07\jre\bin\client\jvm.dll和C:\Java\jdk1.7.0_07\jre\bin\server\jvm.dll)

  2. 接着启动JVM并执行初始化动作,产生Bootstrap ClassLoader

  3. Bootstrap Loader会载入Extended ClassLoader,并设定Extended ClassLoader的parent为Bootstrap ClassLoader

  4. 接着Bootstrap ClassLoader会载入App ClassLoader(System ClassLoader,并将App ClassLoader的parent设定为Extended ClassLoader

  5. 接着App ClassLoader开始载入指定的类。注意这里有个“双亲委派模型”的概念,就是在载入类时,都是先交于parent类ClassLoader去加载,如果找到了就直接 返回,否则才自己来加载,自己也加载不到就抛出ClassNotFoundException,见图:

  6. classLoader加载class的流程_第1张图片


注意,这个三个ClassLoader类之间的父子关系(不是继承关系),仅是语义上的关系,Extended ClassLoader 和 App ClassLoader都是java.net.URLClassLoader的子类。见

public class ClassLoaderTest
{
	public static void main(String[] args)
	{
		ClassLoaderTest ct = new ClassLoaderTest();
		System.out.println(ct.getClass().getClassLoader()); //sun.misc.Launcher$AppClassLoader@1bbf1ca
		System.out.println(ct.getClass().getClassLoader().getParent()); //sun.misc.Launcher$ExtClassLoader@1ff0dde
		System.out.println(ct.getClass().getClassLoader().getParent().getParent()); // null
		// 由于这些系统lib中的类是由BootStrap加载的,它并不是一个类,所以无法获取ClassLoader
		System.out.println(System.class.getClassLoader()); // null
		//App ClassLoader的父类为java.net.URLClassLoader
		System.out.println(ct.getClass().getClassLoader().getClass().getSuperclass().getName());//java.net.URLClassLoader
		//Extended ClassLoader的父类为java.net.URLClassLoader
		System.out.println(ct.getClass().getClassLoader().getParent().getClass().getSuperclass().getName());//java.net.URLClassLoader
	}
}

可见第8行为null,因为Bootstrap ClassLoader是C++编写


可见JVM中默认的classloader有Bootstrap ClassLoader、Extended ClassLoader、App ClassLoader

  1. Bootstrap ClassLoader:负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的jar和class,即系统参数sun.boot.class.path下的jar和类。System.getProperty("sun.boot.class.path")可查看详细,我电脑显示如下:

    C:\Program Files (x86)\Java\jre7\lib\resources.jar;

    C:\Program Files (x86)\Java\jre7\lib\rt.jar;

    C:\Program Files (x86)\Java\jre7\lib\sunrsasign.jar;

    C:\Program Files (x86)\Java\jre7\lib\jsse.jar;

    C:\Program Files (x86)\Java\jre7\lib\jce.jar;

    C:\Program Files (x86)\Java\jre7\lib\charsets.jar;

    C:\Program Files (x86)\Java\jre7\lib\jfr.jar;

    C:\Program Files (x86)\Java\jre7\classes

  2. Extended ClassLoader:负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class等,即系统参数java.ext.dirs下的jar和类,System.getProperty("java.ext.dirs")可查看详细,我电脑显示如下:

    C:\Program Files (x86)\Java\jre7\lib\ext;

    C:\Windows\Sun\Java\lib\ext

  3. App ClassLoader:负责加载当前java应用的classpath中的所有类。即系统参数java.class.path下的jar和类,System.getProperty("java.class.path")可查看详细,我电脑显示如下:

    D:\soft\eclipse\workspace\test\bin;

    D:\soft\eclipse\workspace\test\lib\commons-logging-1.0.4.jar;

    D:\soft\eclipse\workspace\test\lib\commons-cli-1.2.jar;

    D:\soft\eclipse\workspace\test\lib\mysql-connector-java-5.1.28-bin.jar;

    。。。

  4. 1




你可能感兴趣的:(classLoader加载class的流程)