• java虚拟机的类加载器


    一、类的加载可以简单分成两种方式,静态加载和动态加载。

      1、静态加载,就是new等方式使用到一个类的实例时,程序在运行到该处时,会把该类的.class文件加载到jvm里。

      2、动态加载,通过Class.forName()或类加载器的方式,通过类的全名限定把.class文件加载到jvm里。

        forName()方式:

        @Test
        public void testClass() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
            Emp emp = (Emp) Class.forName("entity.Emp").newInstance();
            System.out.println(emp);
        }
        

        结果:

    Emp [name=null, age=0, address=null, date=null]

        类加载的方式:需要一个ClassLoader的实例,运行它的loadClass()方法,一般使用本类的类加载,或自定义类的加载器。  

    @Test
        public void testClassLoader() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
            //本类的类加载器使用方式
            ClassLoader thisLoader = this.getClass().getClassLoader();
            Emp empOne = (Emp) thisLoader.loadClass("entity.Emp").newInstance();
            System.out.println(empOne);
            
            //其他类的使用
            ClassLoader classLoader = Emp.class.getClassLoader();
            Emp empTwo = (Emp) classLoader.loadClass("entity.Emp").newInstance();
            System.out.println(empTwo);
        }

        结果:

    Emp [name=null, age=0, address=null, date=null]
    Emp [name=null, age=0, address=null, date=null]

     二、类加载的机制

      类加载器的层次关系:

      *仅仅是层次关系,非继承关系

      *它并不是一个强制性的约束模型,而是Java设计者推荐给开发者的一种类加载器实现方式

      

      启动类加载器  Bootstrap ClassLoader

        ↑

      扩展类加载器  Extension ClassLoader

        ↑

      应用程序类加载器  Application ClassLoader

        ↑

      自定义类加载器  Custom ClassLoader

       

    1、启动类加载器Bootstrap ClassLoader

      这是一个嵌在JVM内核中的加载器。它负责加载的是JAVA_HOME/lib下的类库,系统类加载器无法被Java程序直接应用

    2、扩展类加载器Extension ClassLoader

      这个类加载器由sun.misc.Launcher$ExtClassLoader实现,它负责用于加载JAVA_HOME/lib/ext目录中的,或者被java.ext.dirs系统变量指定所指定的路径中所有类库,开发者可以直接使用扩展类加载器。java.ext.dirs系统变量所指定的路径的可以通过程序来查看

        @Test
        public void testdirs() {
            System.out.println(System.getProperty("java.ext.dirs"));
        }

      结果:

    D:javajdk1.8.0_91jrelibext;C:WindowsSunJavalibext

    3、应用程序类加载器Application ClassLoader

    这个类加载器由sun.misc.Launcher$AppClassLoader实现。这个类也一般被称为系统类加载器,会加载java.class.path下的类文件。

    这个目录包括了项目中类的.class问价,即编译后项目的bin目录,和项目引用的第三发jar包或通过maven引用的jar包等。

        @Test
        public void testdirs() {
            System.out.println(System.getProperty("java.class.path"));
        }

      结果:

    D:gitasicCodein;C:Userslizihao.p2poolpluginsorg.junit_4.12.0.v201504281640junit.jar;C:Userslizihao.p2poolpluginsorg.hamcrest.core_1.3.0.v20180420-1519.jar;D:gitasicCodejarcommons-io-2.5.jar;D:gitasicCodejardom4j-1.6.1.jar;D:gitasicCodejarsqljdbc42.jar;D:gitasicCodejarojdbc6.jar;D:gitasicCodejarjson-20160810.jar;D:gitasicCodejaritextpdfjararcodes-7.1.4.jar;D:gitasicCodejaritextpdfjarfont-asian-7.1.4.jar;D:gitasicCodejaritextpdfjarforms-7.1.4.jar;D:gitasicCodejaritextpdfjarhyph-7.1.4.jar;D:gitasicCodejaritextpdfjario-7.1.4.jar;D:gitasicCodejaritextpdfjarkernel-7.1.4.jar;D:gitasicCodejaritextpdfjarlayout-7.1.4.jar;D:gitasicCodejaritextpdfjarpdfa-7.1.4.jar;D:gitasicCodejaritextpdfjarsign-7.1.4.jar;D:gitasicCodejaritextpdfjarstyled-xml-parser-7.1.4.jar;D:gitasicCodejaritextpdfjarsvg-7.1.4.jar;D:gitasicCodejaritextpdfjarslf4j-api-1.7.13.jar;D:gitasicCodejarmysql-connector-java-5.1.47.jar;D:javaeclipseeclipseconfigurationorg.eclipse.osgi417.cp;D:javaeclipseeclipseconfigurationorg.eclipse.osgi416.cp

     类加载器:

        @Test
        public void testdirs() {
            System.out.println(this.getClass().getClassLoader());
            System.out.println(this.getClass().getClassLoader().getParent());
            System.out.println(this.getClass().getClassLoader().getParent().getParent());
        }

      结果:

    sun.misc.Launcher$AppClassLoader@60e53b93
    sun.misc.Launcher$ExtClassLoader@27c170f0
    null

    从结果可以看出来,我自定义的测试类的使用的是应用程序类加载器Application ClassLoader,它的父类加载器(非继承意义上的父类)是扩展类加载器Extension ClassLoader,而在往上的启动类加载器Bootstrap ClassLoader是null,因为jvm的一部分,是c/c++写的,所以没有保存在java堆中,其他加载器都是java实现的,类型信息class实例保存在java堆中,虽有可以打印出来。

    三、类加载双亲委派机制

      

    就算这个世道烂成一堆粪坑,那也不是你吃屎的理由
  • 相关阅读:
    一个C# usb与mcu通信的程序,附代码
    基于C#音乐播放器(附代码)
    基于C#俄罗斯方块
    FTP方式部署Azure Web App
    微信接口小例
    基于来信码的短信通知平台
    基于Windows服务的WCF
    基于IIS的WCF
    基于.NET的Excel开发:单元格区域的操作(读取、赋值、边框和格式)
    .NET通过RFC读取SAP数据
  • 原文地址:https://www.cnblogs.com/whalesea/p/10671875.html
Copyright © 2020-2023  润新知