java classLoader

目录

ClassLoader发展过程

ClassLoader概念

自定义Class Loader可以实现的功能

java类加载过程

java类加载器的继承关系

java.lang.ClassLoader


ClassLoader发展过程

        类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java Applet 需要从远程下载 Java 类文件到浏览器中并执行。

        现在类加载器在 Web 容器和 OSGi 中得到了广泛的使用。一般来说,Java 应用的开发人员不需要直接同类加载器进行交互。Java 虚拟机默认的行为就已经足够满足大多数情况的需求了。不过如果遇到了需要与类加载器进行交互的情况。

ClassLoader概念

        classLoader是类加载器,是负责加载类的类,用来动态加载Java 类(class文件)到 Java 虚拟机中并执行。但是,虚拟机启动的时候,并不会一次性加载所有的class文件,而是根据需要去动态加载,因为一次全加载,那内存很容易崩溃。

        JVM设计者把类加载阶段中的“通过‘类全名’来获取定义此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。

        运行Java程序,就是执行java这个命令,指定包含main方法的完整类名,以及一个classpath,即类路径。类路径可以有多个,对于直接的class文件,路径是class文件的根目录,对于jar包,路径是jar包的完整名称(包括路径和jar包名)。Java运行时,会根据类的完全限定名寻找并加载类,寻找的方式基本就是在系统类和指定的类路径中寻找。

自定义Class Loader可以实现的功能

        1、热部署。在不重启Java程序的情况下,动态替换类的实现,比如Java Web开发中的JSP技术就利用自定义的ClassLoader实现修改JSP代码即生效。

        2、应用的模块化和相互隔离。不同的ClassLoader可以加载相同的类但互相隔离、互不影响。Web应用服务器如Tomcat利用这一点在一个程序中管理多个Web应用程序,每个Web应用使用自己的ClassLoader,这些Web应用互不干扰。OSGI和Java 9利用这一点实现了一个动态模块化架构,每个模块有自己的ClassLoader,不同模块可以互不干扰。

        3、从不同地方灵活加载。系统默认的ClassLoader一般从本地的.class文件或jar文件中加载字节码文件,通过自定义的ClassLoader,我们可以从共享的Web服务器、数据库、缓存服务器等其他地方加载字节码文件。

java类加载过程

        Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表示一个 Java 类。 基本上所有的类加载器都是 java.lang.ClassLoader类的一个实例。     

     JVM(虚拟机)把描述类的数据的字节码.Class文件加载到内存,并对数据进行校正、转换解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制

        类从被加载到虚拟机内存中开始,到卸载出内存为止,它的生命周期包括如下七个阶段:

1、加载(查找并加载类的二进制数据):

加载阶段是“类加载机制”中的一个阶段,这个阶段通常也被称作“装载”,主要完成如下工作:

(1)通过“类全名”来获取定义此类的二进制字节流

(2)将字节流所代表的静态存储结构转换为方法区的运行时数据结构

(3)在java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口

2、验证(确保被加载类的正确性):

验证是链接阶段的第一步,这一步主要目的是确保class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全。

3、准备(为类的静态变量分配内存,并将其初始化为默认值)。

4、解析(把类中的符号引用转换为直接引用)。

5、初始化(为类的静态变量赋予正确的初始值)。

java类加载器的继承关系

        Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。

        系统提供的类加载器:

  •         引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。负责加载 java环境变量JAVA_HOME\lib目录中并且能被虚拟机识别的类库到JVM内存中,如果名称不符合的类库即使放在lib目录中也不会被加载。该类加载器无法被Java程序直接引用。
  •         扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。该加载器主要是负责加载 java环境变量JAVA_HOME\lib\ext,该加载器都可以被开发者直接使用。
  •         系统类加载器(App class loader 或者叫 system class loader):它根据 Java 应用的类路径(CLASSPATH,环境变量)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。这个加载器的实现类是sun.misc. Launcher$AppClassLoader。

        启动类加载器(Bootstrap ClassLoader)使用C++语言实现,属于虚拟机自身的一部分,不是ClassLoader的子类。所有其他的类加载器,这些类加载器是由Java语言实现,独立于JVM外部,并且全部继承自抽象类lava.lang.ClassLoader。

java.lang.ClassLoader

        java.lang.ClassLoader类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个 Java 类,即 java.lang.Class 类的一个实例。除此之外, ClassLoader 还负责加载 Java 应用所需的资源,如图像文件和配置文件等。

        类ClassLoader是一个抽象类,Application ClassLoader和ExtensionClassLoader的具体实现类分别是sun.misc.Launcher$AppClassLoader和sun.misc.Launcher$ExtClassLoader, Bootstrap ClassLoader不是由Java实现的,没有对应的类。

        每个应用类Class对象都有一个方法,可以获取实际加载它的ClassLoader,方法是:

        ClassLoader有一个方法,可以获取它的父ClassLoader:

 举例:

 ClassLoader有一个静态方法,可以获取默认的系统类加载器:

ClassLoader中有一个方法loadClass(),用于加载应用类:

 举例:

 java.util.ArrayList实际由BootStrap ClassLoader加载,所以返回值就是null。

 Class的两个静态方法forName:

第一个方法使用系统类加载器加载,第二个方法指定ClassLoader,参数initialize表示加载后是否执行类的初始化代码(如static语句块),没有指定默认为true。

        ClassLoader的loadClass方法与Class的forName方法都可以加载应用类,它们有什么不同呢?基本是一样的,不过,ClassLoader的loadClass不会执行类的初始化代码。

例子:

 使用ClassLoader加载静态内部类Hello, Hello有一个static语句块,输出"hello",运行该程序,类被加载了,但没有任何输出,即static语句块没有被执行。如果将loadClass的语句换为:

则static语句块会被执行,屏幕将输出"hello"。
        loadClass()的内部实现调用另一个loadClass,其中还有调用findClass。

        findClass是一个protected方法,类ClassLoader的默认实现就是抛出ClassNotFoundException。

---------------------------------------------------------------------------------------------------------------------

参考文献:

https://blog.csdn.net/briblue/article/details/54973413

《Java编程的逻辑》第24章 类加载机制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值