从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方法的实现如下:

  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;

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

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

    类加载器的命名空间 每个类加载器又有一个命名空间,由其以及其父加载器组成 类加载器的命名空间的作用和影响 每个类加载器又有一个命名空间,由其以及其父加载器组成 在每个类加载器自己的命名空间中不能出现相 ...

  2. Java中的类加载器

    转载:http://blog.csdn.net/zhangjg_blog/article/details/16102131 从java的动态性到类加载机制   我们知道,Java是一种动态语言.那么怎 ...

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

    类加载器 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过一个类的全限定名来获取定义此类的二进制字 ...

  4. Java中的类加载器--Class loader

    学习一下Java中的类加载器,这个是比较底层的东西,好好学习.理解一下.  一.类加载器的介绍 1.类加载器:就是加载类的工具,在java程序中用到一个类,java虚拟机首先要把这个类的字节码加载到内 ...

  5. Java基础之类加载器

    Java类加载器是用户程序和JVM虚拟机之间的桥梁,在Java程序中起了至关重要的作用,理解它有利于我们写出更优雅的程序.本文首先介绍了Java虚拟机加载程序的过程,简述了Java类加载器的加载方式( ...

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

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 (一)类加载器(class loader) 用来动态加载Java类的工具,它本身也是Java类. ...

  7. 深入理解java虚拟机【类加载机制】

    Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需要完成以下 ...

  8. Java中的类加载器以及Tomcat的类加载机制

    在加载阶段,虚拟机需要完成以下三件事情: 1.通过一个类的全限定名来获取其定义的二进制字节流. 2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构. 3.在Java堆中生成一个代表这个类 ...

  9. 黑马程序员:Java基础总结----类加载器

    黑马程序员:Java基础总结 类加载器   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个 ...

  10. Java基础加强-类加载器

    /*类加载器*/ 把.class文件从硬盘上加载出来,将类的字节码(二进制)加载到内存中 /*类加载器及其委托机制*/ Java虚拟机中可以安装多个类加载器(可以自己编写),系统默认三个主要类加载器, ...

随机推荐

  1. 原生ajax 请求

    什么是ajax AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新. 这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新, ...

  2. 解决jmeter 请求参数中文乱码

    今天在用jmeter 写脚本时发现查看结果树request post请求中文参数值是乱码,故记录下解决过程. 解决过程如下: 1.修改本地配置文件 因为此处的数据,还没有发送出去,所以,肯定是这个变量 ...

  3. ReentrantReadWriteLock源码分析笔记

    ReentrantReadWriteLock包含两把锁,一是读锁ReadLock, 此乃共享锁, 一是写锁WriteLock, 此乃排它锁. 这两把锁都是基于AQS来实现的. 下面通过源码来看看Ree ...

  4. Comet OJ - Contest #12 D

    题目描述 求(x,y)的对数满足x∈[0,a],y∈[0,b],x⊕y=0且|x-y|<=m 题解 一种比较sb的做法是考虑x-y的借位,根据借位以及差值进行转移 还有一种比较正常的做法,假设一 ...

  5. 工作笔记--js-点赞按钮和踩踩按钮互斥??怎么写?

    效果图: html: css: .an{ margin-top:0px; position: relative; .popzframe,.popcframe{ display: none; word- ...

  6. 编译caffe-gpu-cuda及cudnn-tar 下载地址

    y下载 https://github.com/BVLC/caffe https://github.com/BVLC/caffe/archive/master.zip gcc caffe安装 有2个问题 ...

  7. 洛谷 P4151 BZOJ 2115 [WC2011]最大XOR和路径

    //bzoj上的题面太丑了,导致VJ的题面也很丑,于是这题用洛谷的题面 题面描述 XOR(异或)是一种二元逻辑运算,其运算结果当且仅当两个输入的布尔值不相等时才为真,否则为假. XOR 运算的真值表如 ...

  8. 接口自动化request库入门

    requests库7个主要方法 r= requsts.get(),主要属性: r.raise_for_status()方法内部判断r.status_code是否等于200不需要增加额外的if语句,该语 ...

  9. SQL语法——Join详解

    一.INNER JOIN 用法: select column_name(s) from table 1 INNER JOIN table 2 ON table 1.column_name=table ...

  10. 梯度、Hessian矩阵、平面方程的法线以及函数导数的含义

    本文转载自: Xianling Mao的专栏 =========================================================================== 想 ...