深入理解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方法就可以了,剩下的而工作,父类会完成。
- class MyClassLoader extends ClassLoader {
- @Override
- public Class<?> loadClass(String name) throws ClassNotFoundException {
- String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
- InputStream in = getClass().getResourceAsStream(fileName);
- if (in == null) {
- return super.loadClass(name);
- }
- byte[] b = null;
- try {
- b = new byte[in.available()];
- in.read(b);
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return defineClass(name, b, 0, b.length);
- }
- }
其他java平台有的根据自己的需求,实现了自己特定的类加载器,
例如javaee平台中的tomcat服务器,Android平台中的dalvik虚拟机也定义了自己的类加载器。
虚拟机加载类有两种方式,一种方式就是上面提到的ClassLoader.loadClass()方法,
另一种是使用反射API,Class.forName()方法,其实Class.forName()方法内部也是使用的ClassLoader。
指定参数ClassLoader的话就用指定的;否则,返回的是调用者的类加载器。
Class类中forName方法的实现如下:
- public static Class<?> forName(String name, boolean initialize,
- ClassLoader loader)
- throws ClassNotFoundException
- {
- if (loader == null) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null) {
- sm.checkPermission(
- SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
- }
- return forName0(name, initialize, loader);
- }
- /** Called after security checks have been made. */
- private static native Class forName0(String name, boolean initialize,
- ClassLoader loader)
- throws ClassNotFoundException;
深入理解java:1.1. 类加载器的更多相关文章
- 【深入理解Java虚拟机 】类加载器的命名空间以及类的卸载
类加载器的命名空间 每个类加载器又有一个命名空间,由其以及其父加载器组成 类加载器的命名空间的作用和影响 每个类加载器又有一个命名空间,由其以及其父加载器组成 在每个类加载器自己的命名空间中不能出现相 ...
- Java中的类加载器
转载:http://blog.csdn.net/zhangjg_blog/article/details/16102131 从java的动态性到类加载机制 我们知道,Java是一种动态语言.那么怎 ...
- 【深入理解JVM】:类加载器与双亲委派模型
类加载器 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过一个类的全限定名来获取定义此类的二进制字 ...
- Java中的类加载器--Class loader
学习一下Java中的类加载器,这个是比较底层的东西,好好学习.理解一下. 一.类加载器的介绍 1.类加载器:就是加载类的工具,在java程序中用到一个类,java虚拟机首先要把这个类的字节码加载到内 ...
- Java基础之类加载器
Java类加载器是用户程序和JVM虚拟机之间的桥梁,在Java程序中起了至关重要的作用,理解它有利于我们写出更优雅的程序.本文首先介绍了Java虚拟机加载程序的过程,简述了Java类加载器的加载方式( ...
- 黑马程序员——【Java高新技术】——类加载器
---------- android培训.java培训.期待与您交流! ---------- 一.概述 (一)类加载器(class loader) 用来动态加载Java类的工具,它本身也是Java类. ...
- 深入理解java虚拟机【类加载机制】
Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需要完成以下 ...
- Java中的类加载器以及Tomcat的类加载机制
在加载阶段,虚拟机需要完成以下三件事情: 1.通过一个类的全限定名来获取其定义的二进制字节流. 2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构. 3.在Java堆中生成一个代表这个类 ...
- 黑马程序员:Java基础总结----类加载器
黑马程序员:Java基础总结 类加载器 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个 ...
- Java基础加强-类加载器
/*类加载器*/ 把.class文件从硬盘上加载出来,将类的字节码(二进制)加载到内存中 /*类加载器及其委托机制*/ Java虚拟机中可以安装多个类加载器(可以自己编写),系统默认三个主要类加载器, ...
随机推荐
- jpa 自定义sql 删除方法注意点
1.jpa自带的delete()方法可以成功删除对象 delete(id),或者delete(entity) 2.自定义删除方法注意点 参考:https://www.jianshu.com/p/9d5 ...
- Python修炼之路-Socket
网络编程 socket套接字 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过“套接字”向网络发出请求或者应答网络请求. socket ...
- SQL中INEXISTS和IN 的区别和联系
SET NOCOUNT ON , SET NOCOUNT OFF当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数).当 SET NOCOUNT 为 ...
- ansj分词器使用记录
//最简单实例 String ruiec = “分词测试123456100名”; //剔除指定的分词 s.insertStopWords("100名"); //剔除标点符号(w) ...
- 搭建 MySQL 5.7.19 主从复制,以及复制实现细节分析
主从复制可以使MySQL数据库主服务器的主数据库,复制到一个或多个MySQL从服务器从数据库,默认情况下,复制异步; 根据配置,可以复制数据库中的所有数据库,选定的数据库或甚至选定的表. Mysql ...
- HDU-2389-Rain on your Parade (最大匹配,kopcroft-karp)
链接: https://vjudge.net/problem/HDU-2389 题意: You're giving a party in the garden of your villa by the ...
- layui静态表格固定td宽度,table固定td宽度
正在做一个项目,要求数据表的列是不固定的,有可能是有10列,有可能是20列,第一列宽度要固定,然后我怎么设置都没有用, 这个问题困扰了我三天,后来终于百度到了, 这个博客: https://www.c ...
- 结合webpack实现children子路由,抽离路由模块
demo结构 package.json.webpack.config.js.index.html与上一篇博客相同. main.js // 这是项目的入口js文件 // import $ from 'j ...
- grpc:What is gRPC
本文将介绍gRPC和protocol buffers.gRPC可以利用protocol buffers作为其接口定义语言(Interface Definition Language,IDL)和信息交换 ...
- 大文件的分片传,断点续传,md5校验
一.概述 所谓断点续传,其实只是指下载,也就是要从文件已经下载的地方开始继续下载.在以前版本的HTTP协议是不支持断点的,HTTP/1.1开始就支持了.一般断点下载时才用到Range和Content- ...