深入理解java:1.1.类加载器

从java的动态性到类加载机制

我们知道,Java是一种动态语言。

那么怎样理解这个“动态”呢?

或者说一门语言具备了什么特性,才能称之为动态语言呢?

对于java,我是这样理解的。

我们都知道JVM(java虚拟机)执行的不是本地机器码指令,

而是执行一种称之为字节码的指令(存在于class文件中)。

这就要求虚拟机在真正执行字节码之前,先把相关的class文件加载到内存中。

虚拟机不是一次性加载所有需要的class文件,因为它在执行的时候根本不会知道以后会用到哪些class文件。

它是每用到一个类,就会在运行时“动态地”加载和这个类相关的class文件。

这就是java被称之为动态性语言的根本原因。

除了动态加载类之外,还会动态的初始化类,对类进行动态链接。

在JVM中负责对类进行加载的正是本文要介绍的类加载器(ClassLoader),所以,类加载器是JVM不可或缺的重要组件。

java中的类加载器及类加载器工作原理

java中(指的是javase)有三种类加载器。

每个类加载器在创建的时候已经指定他们对应的目录, 也就是说每个类加载器去哪里加载类是确定的,我认为在ClassLoader类中应该会有getTargetPath()之类的方法, 得到他们对应的路径,找了找jdk的文档,发现是没有的。

以下是这三种类加载器和他们对应的路径:

* AppClassLoader  --   加载classpath指定的路径中的类

* ExtClassLoader   --   加载jre/lib/ext目录下或者java.ext.dirs系统属性定义的目录下的类

* BootStrap           --   加载JRE/lib/rt.jar中的类

那么类加载器是如何工作的呢?

可以参看jdk中ClassLoader类的源码。这个类的实现使用了模板方法模式,首先是loadClass方法来加载类,loadClass方法又调用了findClass方法,该方法读取并返回类文件的数据,findClass方法返回后,loadClass方法继续调用defineClass方法,将返回的数据加工成虚拟机运行时可识别的类型信息。

所以,我们如果开发自己的类加载器,只需要继承jdk中的ClassLoader类,并覆盖findClass方法就可以了,剩下的而工作,父类会完成。

  1. class MyClassLoader extends ClassLoader {
  2. @Override
  3. public Class<?> loadClass(String name) throws ClassNotFoundException {
  4. String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
  5. InputStream in = getClass().getResourceAsStream(fileName);
  6. if (in == null) {
  7. return super.loadClass(name);
  8. }
  9. byte[] b = null;
  10. try {
  11. b = new byte[in.available()];
  12. in.read(b);
  13. in.close();
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }
  17. return defineClass(name, b, 0, b.length);
  18. }
  19. }

其他java平台有的根据自己的需求,实现了自己特定的类加载器,

例如javaee平台中的tomcat服务器,Android平台中的dalvik虚拟机也定义了自己的类加载器。

虚拟机加载类有两种方式,一种方式就是上面提到的ClassLoader.loadClass()方法,

另一种是使用反射API,Class.forName()方法,其实Class.forName()方法内部也是使用的ClassLoader。

指定参数ClassLoader的话就用指定的;否则,返回的是调用者的类加载器。

Class类中forName方法的实现如下:

[java]

  1. public static Class<?> forName(String name, boolean initialize,
  2. ClassLoader loader)
  3. throws ClassNotFoundException
  4. {
  5. if (loader == null) {
  6. SecurityManager sm = System.getSecurityManager();
  7. if (sm != null) {
  8. ClassLoader ccl = ClassLoader.getCallerClassLoader();
  9. if (ccl != null) {
  10. sm.checkPermission(
  11. SecurityConstants.GET_CLASSLOADER_PERMISSION);
  12. }
  13. }
  14. }
  15. return forName0(name, initialize, loader);
  16. }
  17. /** Called after security checks have been made. */
  18. private static native Class forName0(String name, boolean initialize,
  19. ClassLoader loader)
  20. throws ClassNotFoundException;
时间: 2024-10-13 22:13:50

深入理解java:1.1.类加载器的相关文章

【深入理解Java虚拟机 】类加载器的命名空间以及类的卸载

类加载器的命名空间 每个类加载器又有一个命名空间,由其以及其父加载器组成 类加载器的命名空间的作用和影响 每个类加载器又有一个命名空间,由其以及其父加载器组成 在每个类加载器自己的命名空间中不能出现相同类名的类 (此处值得是类的全名,包含包名) 在不同的类命名空间中,可能会出现多个相同的类名的类 如下面的代码示例中, 首先定义一个类加载器 MyClassLoader static class MyClassLoader extends ClassLoader { private String c

Java中的类加载器

转载:http://blog.csdn.net/zhangjg_blog/article/details/16102131 从java的动态性到类加载机制 我们知道,Java是一种动态语言.那么怎样理解这个"动态"呢?或者说一门语言具备了什么特性,才能称之为动态语言呢?对于java,我是这样理解的. 我们都知道JVM(java虚拟机)执行的不是本地机器码指令,而是执行一种称之为字节码的指令(存在于class文件中).这就要求虚拟机在真正执行字节码之前,先把相关的class文件加载到内存

【深入理解JVM】:类加载器与双亲委派模型

类加载器 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段"加载"过程中,需要通过一个类的全限定名来获取定义此类的二进制字节流,完成这个动作的代码块就是类加载器.这一动作是放在Java虚拟机外部去实现的,以便让应用程序自己决定如何获取所需的类. 虚拟机规范并没有指明二进制字节流要从一个Class文件获取,或者说根本没有指明从哪里获取.怎样获取.这种开放使得Java在很多领域得到充分运用,例如: 从ZIP包中读

JAVA基础_类加载器

什么是类加载器 类加载器是Java语言在1.0版本就引入的.最初是为了满足JavaApplet需要.现在类加载器在Web容器和OSGI中得到了广泛的应用,一般来说,Java应用的开发人员不需要直接同类加载器进行交互.Java虚拟机默认的行为就已经足够满足大多数情况的需求了.不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时候在ClassNotFoundException和NoClassDefFoundError等异常上. 顾名思义,类加载器是用来加

JAVA之了解类加载器Classloader

1.类的加载.连接和初始化   类初始化通常包括加载.连接.初始化三个步骤. (1)进程的结束 每当运行一个java程序时,将会启动一个java虚拟机进程,不管程序多么复杂,有多少线程,都在这个java虚拟机进程里.以下四种情况会使得该进程被终止-- 程序运行到最后正常结束: 程序里遭遇了System.exit(),或者是Runtime.getRunTime().exit()代码: 程序执行中遇到了未捕获的异常或者错误: java所在平台强制结束了JVM进程: 当该进程结束,那么该进程在内存中的

黑马程序员——【Java高新技术】——类加载器

一.概述 (一)类加载器(class loader) 用来动态加载Java类的工具,它本身也是Java类. (二)类加载器作用 负责加载 Java 类的字节代码到 Java 虚拟机中. (三)Java类加载器 1.Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类加载器负责加载特定位置的类: (1)BootStrap(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader.

【深入理解Java虚拟机】类加载机制

本文内容来源于<深入理解Java虚拟机>一书,非常推荐大家去看一下这本书. 本系列其他文章: [深入理解Java虚拟机]Java内存区域模型.对象创建过程.常见OOM [深入理解Java虚拟机]垃圾回收机制 1.类加载机制概述 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 在java中,类型的加载.连接和初始化过程都是在程序运行期间完成的,这种策略虽然会带来一些性能开销,但是却为jav

[读书笔记]java中的类加载器

以下内容大多来自周志明的<深入理解Java虚拟机>. 类加载器是java的一项创新,也是java流行的重要原因之一,它最初是为了满足java applet的需求而开发出来. 什么是applet? 作为新手,都不知道applet是什么鬼,看看百度百科的解释,应该就明白了: JavaApplet就是用Java语言编写的小应用程序,可以直接嵌入到网页中,并能够产生特殊的效果. 所以Applet就目前来看 我们用不到了,但是类加载器却在类层次划分.OSGI.热部署.代码加密等领域大放异彩,成为了JAV

java基础之—类加载器

要了解类加载器先要了解类的加载 一.类的加载(类的加载概述) 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 1.加载 就是指将class文件读入内存,并为之创建一个Class对象. 任何类被使用时系统都会建立一个Class对象. 其中class对象也就是下一章节要将的反射的重点. 其中这个class对象描述了这个对象的所有信息,比如都有哪些构造方法,都有哪些成员方法,都有哪些字段等. 2.连接 验证 是否有正确的内部结构,并和其他

java jvm虚拟机类加载器

在Java中任意一个类都是由这个类本身和加载这个类的类加载器来确定这个类在JVM中的唯一性. 类加载器 虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现, 以便让应用程序自己决定如何去获取所需要的类. 实现这个动作的代码模块称为“类加载器”. 类与类加载器 类加载器虽然只用于实现类的加载动作, 但它在Java程序中起到的作用却远远不限于类加载阶段. 对于任意一个类, 都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟