Java类加载器以及类加载器的委托模型

我们知道,我们在Java中用到的所有的类都是通过类加载器ClassLoader加载到JVM中的,我们还知道类加载器也对应着一个类,既然这样那么我们会想那么ClassLoader类是由谁加载的呢?

  其实在Java中有许许多多的类加载器,我们甚至可以写自己的类加载器。

  其中主要三个类加载器(他们是树形关系)是:

  BootStrap:在java虚拟机启动的时候会利用这个类加载器来加载 JDK安装目录下的 /JRE/LIB/rt.jar 也就是系统默认导入的一些类例如System类,这个类加载器不是类 。只是作为一个java中类的起源工具。

  ExpClassLoader:这个类加载器加载JDK安装目录下的/JRE/LIB/ext 目录中的类 我们只要把我们的类打包成JAR包放在这里即可。

  AppClassLoader:我们在java程序中classpath对应的类都有这个AppClassLoader导入进来。

  看下面一段代码:

  1. package me.test;  
  2. /** 
  3. *   BootStrap   
  4. *   加载  JRE/lib/rt.jar 包中的类   包括我们常用到的类 
  5. *   
  6. *   ExtClassLoader 
  7. *   专门家在 JDK/JRE/libEXT/*.jar  中的类  只要把我们的类放在这里 就会被 这个加载器加载  
  8. *   AppClassLoader   
  9. *   加载ClassPath指定的所有jar和目录 
  10. * **/ 
  11. public class Test1  
  12. {    
  13. public static void main(String []args)  
  14. {  
  15.      
  16.   System.out.println(Test1.class.getClassLoader().getClass().getName() );    //获取主类的类加载器 
  17.   System.out.println(System.class.getClassLoader()); 
  18. //BootStrap    获取System类的类加载器  因为加载器是 BootStrap所以返回null  以为内他不是一个类 
  19.   ClassLoader l=Test1.class.getClassLoader() ;  //获取Test1的类加载器 
  20.   while(l!=null)   //循环出 ClassLoader树 
  21.   {  
  22.    System.out.println(l.getClass().getName());    
  23.    l=l.getParent();  
  24.   }  
  25.    
  26.   System.out.println(l);  
  27.    
  28. }  
  29. }

  ClassLoader的委托模型

  比如说我们在加载一个类的时候AppClassLoader他先让BootStrap来加载类,如果BootStrap已经加载了,那么就返回。如果找不到这个类那么BootStrap就传递给ExtClassLoader 来查找,和BootStrap一样。如果找到就加载,如果找不到就继续传递给AppClassLoader 来加载。如果AppClassLoader还找不到的话,那么AppClassLoader就会跑出ClassNotFoundException 异常。

  我们为什么不利用AppClassLoader下级的加载器呢?因为AppClassLoader下级可能有多个类加载器多个类加载器相互独立,如果加载类那么就会导致内存中出现多份字节码,造成不必要的的内存浪费。这就是类加载器的委托模型。

本文出自seven的测试人生公众号最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-09-20 05:38:00

Java类加载器以及类加载器的委托模型的相关文章

Java类加载器(一)——类加载器层次与模型

类加载器   虚拟机设计团队把类加载阶段中的"通过一个类的全限定名来获取描述此类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称为"类加载器". 类加载器层次(等级)   从JVM的角度来讲,只存在两种不同的类加载器.   第一类是启动类加载器(Bootstrap ClassLoader):这个类加载器主要加载JVM自身工作需要的类.这个类加载器由C++语言实现(特指HotSpot),是虚拟机

Java魔法堂:类加载器入了个门

一.前言   <Java魔法堂:类加载机制入了个门>中提及整个类加载流程中只有加载阶段作为码农的我们可以入手干预,其余均由JVM处理.本文将记录加载阶段的核心组件--类加载器的相关信息,以便日后查阅.若有纰漏请大家指正,谢谢.   注意:以下内容基于JDK7和HotSpot VM.   二.类加载器种类及其关系 从上图可知Java主要有4种类加载器 1. Bootstrap ClassLoader(引导类加载器):作为JVM的一部分无法在应用程序中直接引用,由C/C++实现(其他JVM可能通过

Java类加载原理及类加载器

Java和其他语言不同的是,Java是运行于Java虚拟机(JVM).这就意味着编译后的代码是以一种和平台无关的格式保存的,而不是某种特定的机器上运行的格式.这种格式和传统的可执行代码格式有很多重要的区别.具体来说,不同于C或者C++程序,Java程序不是一个独立的可执行文件,而是由很多分开的类文件组成,每个类文件对应一个Java类. 另外,这些类文件并不是马上加载到内存,而是当程序需要的时候才加载. 类加载器就是Java虚拟机中用来把类加载到内存的工具.而且,Java类加载器也是用Java实现

Fenzo:来自Netflix基于Java语言的Mesos调度器

本文讲的是Fenzo:来自Netflix基于Java语言的Mesos调度器,[编者的话]Fenzo是一个在Mesos框架上应用的通用任务调度器.它可以让你通过实现各种优化策略的插件,来优化任务调度,同时这也有利于集群的自动缩放. Netflix有着数百万的用户,要为这个数量级的用户提供可靠的服务并不是一件容易的事情.Netflix是由几十个分布式的服务支撑的,其中每个服务都是产品不可或缺的一部分,并且都在不断迭代着.我们需要从两个方面来优化这些服务,一个是用户体验,另外一个是服务的整体性能以及成

实现Java中的高性能解析器

在某些情况下,你可能需要在Java中实现你自己的数据或语言解析器,也许是这种数据格式或语言缺乏标准的Java或开源解析器可以使用.或者虽然有现成的解析器实现,但它们要么太慢,要么太占内存,要么就是没有符合你所需要的特性.又或者是某个开源的解析器存在缺陷,要么是某个开源解析器的项目中止了,原因不一而足.不过无论原因是什么,总之事实就是你必须要自己去实现这个解析器. 当你必须自己实现一个解析器时,你对它的期望会有很多,包括性能良好.灵活.特性丰富.方便使用,以及便于维护等等.说到底,这也是你自己的代

groovy/java自实现json解析器(1)绪论

groovy是一门以java为基础的动态语言,它强大地动态特性为我们的敏捷开发带来了极大的便利,下面是一个由grovvy(完美兼容嵌套java实现的json)解析器的部分代码展示,我们都知道,json字符串只要满足格式要求,那么它是可以无限循环嵌套的,而本解析器的核心实现就是大量的递归函数运用,将json字符串一层层地解析开,并拼装成我们相应的数组或对象.它主要由以下五个类组成: --JsonObject.groovy --JsonArray.groovy --JsonTool.groovy -

groovy/java自实现json解析器(2)JsonObject

底层数据结构实现 本对象的底层数据结构是一个Map(映射),我们用def private jsonMap将其定义为对象变量.我们在构造函数中对其进行初始化,它以键值对的形式存储数据,其中键必须为字符串,值可以为字符串.Boolean.Integer.JsonArray.JsonObject,从最后两个可存储对象,我们或多或少地已能看出JsonObject是如何达成普通json对象里的无限嵌套了. 下面是本对象的构造函数. def JsonObject( jsonMap = null) { thi

Java实现的Windows资源管理器实例_java

本文实例讲述了Java实现的Windows资源管理器.分享给大家供大家参考.具体如下: FileTree.java文件如下: // FileTree.java /*********************************************************** * Author: Jason * email: tl21cen@hotmail.com * CSDN blog: http://blog.csdn.net/UnAgain/ *********************

java中用vlc做视频播放器问题

问题描述 java中用vlc做视频播放器问题 一共两个类,第二个是界面,看别人视频做的,结果视频播放不了,求解答. public class PlayMain { static MainWindow frame; public static void main(String[] args) { NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "D:\Program Files\VideoLAN\VLC");