zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    关于在MAC上进行 LARAVEL 环境 Homestead 安装过程记录
    js 贷款计算器
    js 实现阶乘
    js 两点间距离函数
    composer Your requirements could not be resolved to an installable set of packages
    vue 项目优化记录 持续更新...
    vue 项目打包
    vue 真机调试页面出现空白
    vue 真机调试
    谈谈-Android状态栏的编辑
  • 原文地址:https://www.cnblogs.com/cmf12/p/13550108.html
Copyright © 2011-2022 走看看