欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

classloader类加载器_基于java类的加载方式详解

程序员文章站 2024-02-22 11:04:40
基础概念 classloader 类加载器,用来加载 java 类到 java 虚拟机中。与普通程序不同的是。java程序(class文件)并不是本地的可执行程序。当...

基础概念

classloader 类加载器,用来加载 java 类到 java 虚拟机中。与普通程序不同的是。java程序(class文件)并不是本地的可执行程序。当运行java程序时,首先运行jvm(java虚拟机),然后再把java class加载到jvm里头运行,负责加载java class的这部分就叫做class loader。

jvm本身包含了一个classloader称为bootstrap classloader,和jvm一样,bootstrapclassloader是用本地代码实现的,它负责加载核心javaclass(即所有java.*开头的类)。另外jvm还会提供两个classloader,它们都是用java语言编写的,由bootstrapclassloader加载;其中extension classloader负责加载扩展的javaclass(例如所有javax.*开头的类和存放在jre的ext目录下的类),applicationclassloader负责加载应用程序自身的类。

当运行一个程序的时候,jvm启动,运行bootstrapclassloader,该classloader加载java核心api(extclassloader和appclassloader也在此时被加载),然后调用extclassloader加载扩展api,最后appclassloader加载classpath目录下定义的class,这就是一个程序最基本的加载流程。

注: 学classloader看osgi程序应用

什么时候jvm会使用classloader加载一个类呢?当你使用java去执行一个类,jvm使用applicationclassloader加载这个类;然后如果类a引用了类b,不管是直接引用还是用class.forname()引用,jvm就会找到加载类a的classloader,并用这个classloader来加载类b。jvm按照运行时的有效执行语句,来决定是否需要装载新类,从而装载尽可能少的类,这一点和编译类是不相同的。

why use your own classloader?

似乎jvm自身的classloader已经足够了,为什么我们还需要创建自己的classloader呢?

因为jvm自带的classloader只是懂得从本地文件系统加载标准的java class文件,如果编写你自己的classloader,你可以做到:

1)在执行非置信代码之前,自动验证数字签名

2)动态地创建符合用户特定需要的定制化构建类

3)从特定的场所取得java class,例如数据库中

4) 等等

事实上当使用applet的时候,就用到了特定的classloader,因为这时需要从网络上加载java class,并且要检查相关的安全信息。

应用服务器大都使用了classloader技术,即使你不需要创建自己的classloader,了解其原理也有助于更好地部署自己的应用。

重点注明:其实一个已经加载的类是无法被更新的,如果你试图用同一个classloader再次加载同一个类,就会得到异常(java.lang.linkageerror: duplicate classdefinition),我们只能够重新创建一个新的classloader实例来再次加载新类。至于原来已经加载的类,开发人员不必去管它,因为它可能还有实例正在被使用,只要相关的实例都被内存回收了,那么jvm就会在适当的时候把不会再使用的类卸载。

绝大部分java程序都会使用3种系统提供的类加载器

1.启动类加载器(bootstrap classloader),负责将存在<java_home>\lib目录中的,或被-xbootclasspath参数所指定的路径中的,并且是虚拟机识别的类库加载到虚拟机里.注意是按照文件名识别,如rt.jar,名字不符合的类库即使放在lib目录中也不会被加载。

2.扩展类加载器(extclassloader),它负责<java_home>\lib\ext目录中的,或被java.ext.dirs系统变量所指定的路径中的所有类库.

3.应用程序类加载器(app-classloader),通过cassloader.getsystemclassloader()获取,它负责加载用户类路径(classpath)上所指定的类库,一般情况下这个是程序中默认的类加载器.

双亲委托模式 是java设计者推荐给开发者的一种类加载实现方式.双亲委托模型的工作过程是:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成.每一层次的类加载器都是如此,因此所有的加载请求最终都会传送到顶层的启动类加载器中,只有当父类加载器没有找到所需的类时,子加载器才会尝试自己去加载。双亲模式的好处是java类随着它的类加载器一起具备了一种带优先级的层次关系。例如类object,存放在rt.jar中,无论哪个类加载器加载这个类,最终都是委派给处于模型最顶端的启动类加载,因此object类在程序使用多种类加载器环境中依然能保证是同一个类。相反,如果没有使用双亲模型,就可能出现用户自己编写一个object类,导致系统中出现多个不同的object类,这样java类型体系中最基础的行为也就无法保证。

以上这篇classloader类加载器_基于java类的加载方式详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。