Java类加载机制(一):类加载器及其对应的加载路径

在讨论这个问题之前,我们先看看Java的两个重要的环境变量:Path与CLASSPATH

Path与CLASSPATH

Windows环境变量中的Path是用来指明Windows的可执行文件的路径。在安装JDK时,我们通常需要在Path的环境变量中添加java的可执行文件路径%JAVA_HOME%\bin,这样我们就可以在命令行中直接使用java、javac等命令,而无需添加这些可执行文件所在的路径。

CLASSPATH环境变量用于指定加载class文件时的搜索路径。会通过下面的实例说明CLASSPATH的意义。

Java的3种类加载器及其对应的加载路径

了解Java类加载机制应该就会知道,Java提供了3中类加载器:启动类加载器、扩展类加载器和应用程序类加载器。它们分别负责加载不同路径下的类库。在eclipse中通过下面的程序来打印出它们各自的加载路径:

package com.curry.classload;

import java.net.URL;
import java.net.URLClassLoader;

public class ClassLoaderTest {
	
	public static void main(String[] args)
	{
		System.out.println("BootstrapClassLoader 的加载路径: ");
		
		//String[] bootUrls = System.getProperty("sun.boot.class.path").split(";");
		
		URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
		for(URL url : urls)
			System.out.println(url);
		System.out.println("----------------------------");
				
		//取得扩展类加载器
		URLClassLoader extClassLoader = (URLClassLoader)ClassLoader.getSystemClassLoader().getParent();
 
		System.out.println(extClassLoader);
		System.out.println("扩展类加载器 的加载路径: ");
		
		urls = extClassLoader.getURLs();
		for(URL url : urls)
			System.out.println(url);
		
		System.out.println("----------------------------");
				
		
		//取得应用(系统)类加载器
		URLClassLoader appClassLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
		
		System.out.println(appClassLoader);
		System.out.println("应用(系统)类加载器 的加载路径: ");
		
		urls = appClassLoader.getURLs();
		for(URL url : urls)
			System.out.println(url);
				
		System.out.println("----------------------------");	
	}

}

得到的打印结果为:

BootstrapClassLoader 的加载路径: 
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/resources.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/rt.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/sunrsasign.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/jsse.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/jce.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/charsets.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/jfr.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/classes
----------------------------
sun.misc.Launcher$ExtClassLoader@15db9742
扩展类加载器 的加载路径: 
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/access-bridge-64.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/cldrdata.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/dnsns.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/jaccess.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/jfxrt.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/localedata.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/nashorn.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/sunec.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/sunjce_provider.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/sunmscapi.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/sunpkcs11.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/zipfs.jar
----------------------------
sun.misc.Launcher$AppClassLoader@73d16e93
应用(系统)类加载器 的加载路径: 
file:/C:/Users/Welcome/Documents/Eclipse/JVMInPractice/bin/
----------------------------

可以看出:启动类加载器的加载路径为%JAVA_HOME/jre,扩展类加载器的加载路径为%JAVA_HOME/jre/lib/ext,而应用程序类加载器的加载路径为该eclipse工程的类库。如果直接通过命令行编译并执行ClassLoaderTest.java文件,打印结果如下:

BootstrapClassLoader's load path:
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/resources.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/rt.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/sunrsasign.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/jsse.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/jce.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/charsets.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/jfr.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/classes
----------------------------
sun.misc.Launcher$ExtClassLoader@15db9742
extClassLoader's load path:
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/access-bridge-64.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/cldrdata.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/dnsns.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/jaccess.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/jfxrt.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/localedata.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/nashorn.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/sunec.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/sunjce_provider.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/sunmscapi.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/sunpkcs11.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/jre/lib/ext/zipfs.jar
----------------------------
sun.misc.Launcher$AppClassLoader@73d16e93
application classloader's load path:
file:/C:/Users/Welcome/Desktop/java/thought_oN_JVM/
file:/C:/Program%20Files/Java/jdk1.8.0_121/lib/dt.jar
file:/C:/Program%20Files/Java/jdk1.8.0_121/lib/tools.jar
----------------------------

可以发现:

(1)启动类加载器和扩展类加载器的加载路径没有发生变化。启动类加载器加载JAVA_HOME/jre下的核心类库,扩展类加载器加载JAVA_HOME/jre/lib/ext下的扩展类库

(2)应用程序类加载器的加载路径发生变化,这是因为eclipse会将其工程的CLASSPATH设置为这个工程专属的类库路径,而直接在命令行中编译执行时,应用程序类加载器的加载路径就是环境变量CLASSPATH的值。因此可以看出,java提供的应用程序类加载器负责的是CLASSPATH下类库的加载,如果用户程序没有自定义自己的类加载器,那么用户类一般情况下就是由应用程序类加载器加载。

参考文献

https://blog.csdn.net/irelandken/article/details/7048817

 

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值