• Java关键技术强化:类加载器 (day05)


    概述

    1、类加载器

      顾名思义,它就是用来加载Class文件到JVM,以供程序使用的。

    JAVA的类加载,都是通过类加载器完成的。

     

    2、类加载器的创建

      当java运行class文件时,java运行程序会尝试找到JRE安装的所在目录,然后寻找jvm.dll(默认安装在binclient目录中)

    接着启动JVM 并进行初始化的工作,产生Bootstrap Loader,Bootstrap Loader会加载Extended Loader和AppClass Loader。

    Bootstrap Loader是Extended Loader的parent Loader Extended Loader是AppClass Loader的parent Loader

     

    3、类加载器介绍

     

    •  Java内置的ClassLoader

    1、 Bootstrap Loader (引导类加载器) 其实现依赖于底层操作系统,由C编写而成,没有继承于ClassLoader类。根类加载器从系统属性sun.boot.class.path所指定的目录中加载类库。默认为jre目录下的 lib目录下的.class文件 该加载器没有父加载器。负责加载虚拟机的核心类库,如java.lang.*。Object类就是由根类加载器加载的。

    2.、Extended Loader (标准扩展类加载器) 它的父加载器为根类加载器。由Java编写而成,是ClassLoader的子类。 它从java.ext.dirs中加载类库,或者从JDK安装目录jrelibext子目录下加载类库。 如果把用户创建的jar文件放在该目录下,也会自动由扩展类加载器加载 。

    3. AppClass Loader(应用程序类路径类加载器) 父加载器为扩展类加载器。由Java编写而成,是ClassLoader的子类 它从环境变量classpath或者系统属性java.class.path所指定的目录中加载类,是用户自定义的类加载器的默认父加载器。

     

    4、类加载器工作原理

      每个类加载器会先将加载类的任务交给其parent,如果parent找不到,再由自己负责加载。

    所以在加载类时,会以Bootstrap Loader —— Extended Loader —— AppClass Loader 的顺序来寻找类,如果找不到,就会丢出NoClassDefFoundError。

    5、Class和ClassLoader

    •     类加载器在Java中是以java.lang.ClassLoader类型存在 每一个类被加载后,都会有一个Class的实例来代表,而每个Class的实例都会记得自己是由哪个ClassLoader加载的。
    •   可以通过Class的getClassLoader()取得加载该类的ClassLoader。
    •   可以通过ClassLoader的getParent()取得自己的parent 注意:返回null并不代表没有parent,因为Bootstrap Loader 是用C语言编写的,所以没有一个实际的类来表示它。
    •   可以通过ClassLoader的loadClass()加载类。这时不会立即运行静态块,会等到创建类的实例时才会运行。

    代码示例

     1 package work3;
     2 
     3 public class Work3 {
     4     /*
     5     * @param args
     6     * @throws ClassNotFoundException
     7     * */
     8     public static void main(String[] args) {
     9         Class clz;
    10         ClassLoader cl,cl1;
    11 
    12         System.out.println("1------------------");
    13 //        得到系统类加载器
    14         cl = ClassLoader.getSystemClassLoader();
    15         System.out.println(cl);
    16 
    17 //        输出其父加载器
    18         while(cl != null){
    19             cl1 = cl;
    20             cl = cl1.getParent();
    21             System.out.println(cl1+"的父加载器是:"+cl);
    22         }
    23 
    24         System.out.println("2------------------");
    25         try {
    26             clz = Class.forName("java.lang.Object");
    27             cl = clz.getClassLoader();
    28             System.out.println("加载Object类的类加载器是:"+cl);
    29         } catch (ClassNotFoundException e) {
    30             e.printStackTrace();
    31         }
    32 
    33         System.out.println("3------------------");
    34         clz = Work3.class;
    35         cl = clz.getClassLoader();
    36         System.out.println("加载当前类的类加载器是:"+cl);
    37     }
    38 }

     

     运行效果

    1 1------------------
    2 sun.misc.Launcher$AppClassLoader@14dad5dc
    3 sun.misc.Launcher$AppClassLoader@14dad5dc的父加载器是:sun.misc.Launcher$ExtClassLoader@28d93b30
    4 sun.misc.Launcher$ExtClassLoader@28d93b30的父加载器是:null
    5 2------------------
    6 加载Object类的类加载器是:null
    7 3------------------
    8 加载当前类的类加载器是:sun.misc.Launcher$AppClassLoader@14dad5dc

     

    6、类的加载过程

    类的加载分为三个部分:装载、连接、初始化三个过程。装载是将类做为二进制流读到内存中;

    连接是将二进制流转换成类对象(class对象) ,并加载初始化类所需要的资源;

    初始化是初始化类变量或执行static静态块,并为类对象(Class的实例)分配内存空间。

     

    7、类加载器树状组织结构示意图

    8、类的死亡

      类也能被垃圾回收。类被回收的条件有二条: 如果程序没有对Class对象保持明确的引用。 并且堆中没有一个此类的对象。

    总结

      心得总结

        不怕你迈的步子太小,只怕你停滞不前;不怕你做的事太少,只怕你无所事事。任何的收获都不是偶然和巧合,而是日复一日的付出和努力换来。今天一点一滴的进步,终会塑造一个与众不同的你。

        人总是会有懒惰的时刻,昨天停更了一天,今天要继续更新博客,再接再厉!

        有兴趣了解java或者想多跟作者交流的可以加qq--》1265987500

        相信困难总会过去,相信坚持的意义。

  • 相关阅读:
    JavaScript
    HTML
    DockerDesktop安装mysql
    c语言ld returned 1 exit status😂
    eclipse项目导入idea jdk版本不一致😵
    markdown语法
    【Kali】Kali Linux更新5.2.9后 Vmware Workstation无法正常启动
    【NetDevOps】网络自动化运维--1获取用户基本信息
    【NetDevops】网络自动化运维--1获取用户基本信息
    Kali Linux中安装Python虚拟环境
  • 原文地址:https://www.cnblogs.com/cmf12/p/13550108.html
Copyright © 2020-2023  润新知