博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
类加载器(二)
阅读量:6256 次
发布时间:2019-06-22

本文共 2145 字,大约阅读时间需要 7 分钟。

一切都是由Bootstrap Loader开始:类加载器的阶层体系

 

Java程序在编译之后会产生许多的执行单位(.class),当我们执行主类时(public static void main(String arg[])方法的类),才由虚拟机一一载入所有需要的执行单位,变成一个逻辑上为一体的Java应用程序。下面将细部讨论这整个流程。

 

当我们在命令行输入java xxx.class时,java.exe根据我们之前所提过的逻辑找到JRE,接着找到在JRE之中的jvm.dll(真正的Java虚拟机),最后载入这个动态连结函数库,启动Java虚拟机。

虚拟机一启动,会先做一些初始化的动作,比方说抓取系统参数等。一旦初始化动作完成之后,就会产生第一个类加载器,即所谓的Bootstrap Loader,Bootstrap Loader是由C++编写的。这个Loader所做的初始化工作中,除了也做一些基本的初始化动作之外,最重要的就是载入定义在sun.msic命名空间底下的Launcher.java之中的ExtClassLoader(因此是inner class,所以编译之后会变成Launcher$ExtClassLoader.class),并设定其parentnull,代表其父类加载器为Bootstrap Loader。然后Bootstrap Loader再要求载入定义在sun.misc命名空间下的Launcher.java之中的AppClassLoader(因此是inner class,所以编译之后会变成Launcher$AppClassLoader.class),并设定其parent为之前产生的ExtClassLoader实例。这里需要注意的是:Launcher$ExtClassLoader.classLauncher$AppClassLoader.class都是由Bootstrap Loader所载入,所以parent和由那个类加载器载入没有关系。可以用下图表示:

 

 

AppClassLoadersun官方文件中常常又被称作系统加载器(System Loader)。最后一个步骤,是由AppClassLoader负责载入我们在命令行之中所输入的xxx.class(注意:实际上xxx.class很可能是由ExtClassLoaderBootstrap Loader载入,参考下一篇博文的【委派模型】),然后开始一个Java应用程序的生命周期。整个流程如下图:

 

这个由Bootstrap Loader-->ExtClassLoader-->AppClassLoader,就是我们所谓的类加载器的阶层体系。

 

再次强调,类加载器由谁载入(这句话有点诡异,类加载器也要由类加载器载入,这是因为除了Bootstrap Loader之外,其余的类加载器都是由Java所编写),和它的parent是谁没有关系,parent的存在只是为了某些特殊目的,这个目的之后再作解析。三个主要的加载器的关系如下图:

 

在此要注意的是,AppClassLoaderExtClassLoader都是URLClassLoader的子类。由于它们都是URLClassLoader的子类,所以它们也应该有URL作为搜索类的参考,由源代码我们可以得知:

AppClassLoader所参考的URL是从系统参数java.class.path取出的字符串所决定,而java.class.path则是由我们在执行java.exe时,利用-cp-classpathCLASSPATH环境变量所决定。在预设定情况下,AppClassLoader的搜索路径为"."(目前所在目录),如果使用-classpath(-cp等效),就可以改变AppClassLoader的搜索路径,如果没有指定-classpath,就会搜索环境变量CLASSPATH

ExtClassLoader搜索路径参考系统参数java.ext.dirs,会指向java.exe所选择的JRE所在位置下的\lib\ext子目录。

Bootstrap Loader的搜索路径由系统参数sun.boot.class.path指定。

注意:AppClassLoaderBootstrap Loader只会搜索指定的路径,不会迂回搜索这些位置下的其他路径或者没有指定的JAR文件。而ExtClassLoader会搜索底下所有的JAR文件以及classes目录,作为其搜索路径。

 

AppClassLoaderExtClassLoader在整个虚拟机中只存在一份,一旦建立了,其内部所参考的搜索路径将不再改变,也就是说,即使我们在程序里利用System.setProperty()来改变系统参数的内容,仍然无法更改搜索路径。因此,执行时期动态更改搜索路径的设定是不可能的事情。如果因为特殊需求,有些类的所在路径并非在一开始时就能决定,那么除了产生新的类加载器来辅助我们载入所需要的类之外,没有其它方法了。

 

 

转载于:https://www.cnblogs.com/rason2008/archive/2012/01/07/2316122.html

你可能感兴趣的文章
(转)android拨打电话崩溃6.0以上实时动态权限申请
查看>>
懒加载的使用
查看>>
ios xcode 下 报出 ”xx“is missing from working copy 的问题
查看>>
SpringMVC报错The request sent by the client was syntactically incorrect ()
查看>>
网络层封装
查看>>
《c程序设计语言》读书笔记-4.13-递归版本reverse函数
查看>>
background-clip&background-origin
查看>>
论坛迁移日记——discuz X2.5 迁移详细教程
查看>>
拦截器的执行顺序
查看>>
GestureDetector类及其用法
查看>>
String+变量”的操作是在运行时进行
查看>>
(待解决,效率低下)47. Permutations II C++回溯法
查看>>
工作两年
查看>>
201521123081《Java程序设计》 第10周学习总结
查看>>
UI组件-UITextView
查看>>
WPF中ListBox控件选择多个数据项
查看>>
七个小矮人测试随笔
查看>>
yum lnmp
查看>>
OC-id、构造方法
查看>>
Ps操作技巧(快捷键大全)
查看>>