从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. Educational Codeforces Round 77 比赛总结

    比赛情况 我太菜了 A题 加减乘除不会 B题 二元一次方程不会 C题 gcd不会 就会一个D题二分答案大水题,本来想比赛最后一分钟来一个绝杀,结果 Wrong Answer on test 4 比赛总 ...

  2. DevExpress v19.1新版亮点——WinForms篇(五)

    行业领先的.NET界面控件DevExpress v19.1终于正式发布,本站将以连载的形式介绍各版本新增内容.在本系列文章中将为大家介绍DevExpress WinForms v19.1中新增的一些控 ...

  3. puppet运维自动化之用户管理

    系统管理员离不开账户管理,账户管理,密码管理,开发机器,测试机器,线上机器,都需要创建用户,并给与相关用户的权限.你如果要创建100个,1000个账户和密码,你会不会疯掉,如何在1分钟完成百上千个账户 ...

  4. java面向对象4-多态

    5 多态 5.1多态:polymorphism概念 定义:某一类事物的多种存在形态表现形式:父类变量指向子类实例 例:动物中猫,狗 猫这个对象对应的类型是猫类型 猫 x = new 猫(); 同时猫也 ...

  5. 原生ajax 请求

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

  6. 【NOIP2016提高A组模拟9.17】序列

    题目 分析 首先用\(a_i\)表示达到目标的步数\(B_i-A_i(mod 4)\) 根据粉刷栅栏,先不管mod 4的情况,答案就是\(\sum\max(a_i-a_{i+1},0)\) 那我们刚才 ...

  7. 【NOIP2016提高A组模拟8.17】(雅礼联考day1)Matrix

    题目 分析 假设,我们从\(F_{i,2}\)出发,那么对\(F_{n,n}\)的贡献就是\(某个系数乘以a^{n-i}b^{n-1}r_i\): 同理,如果从\(F_{2,i}\)出发,那么对\(F ...

  8. git 清除缓存

    清除git缓存 git config --local --unset credential.helper git config --global --unset credential.helper g ...

  9. Linux的解压缩相关命令

    Linux的解压缩相关命令 知识点: 1.zip命令 2.tar命令 3.压缩和解压常用组合

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

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