java中的动态加载和热替换
https://blog.csdn.net/u010833547/article/details/54312052
*************************************************************
1.C++编写的程序需要经过编译称为目标文件,然后在程序执行之前进行链接后才可以称为可以运行的可执行程序,这个链接可以发生在程序运行之前,也可以发生在程序运行后(在内核中完成链接过程)再被执行。(运行可以理解为双击打开)。而Java则只需要编译成字节码,然后交给JVM解析器去链接执行就可以了。(C++系列也拥有动态加载和动态链接等概念)
2.Java的动态加载实际上就是程序在执行过程中可以根据程序设定去加载需要被执行的字节码文件。
3.热替换属于动态加载的一种,但是热替换是特殊的动态加载机制。
4.动态加载在Java中有2种实现,第一种通过ClassLoader.loadClass()去加载,ClassLoader最高级别的类加载器,所有的类都归他管理,用loadClass加载的类,是未经过初始化的,所以很多静态变量和方法无法被使用,第二种方法则是,Class.forName().用这个方法加载的类已经经过初始化。
5.而如何实现热替换呢?首先我们要知道ClassLoader中的loadClass在加载类的时候会检测该类是否已经存在,如果存在则不会去加载,如果不存在则加载该类并缓存。所以默认的ClassLoader是无法实现热替换的。换句话说,要实现热替换就必须实现一个自己的MyClassLoader,实现一个自己的用于加载类的方法findClass(),在方法里面要做的事情就是读取本地字节码文件,只用父类的defineClass()方法去解析它。这样就可以获取新的类了,而旧的类由于ClassLoader不可达,所以会被GC回收。
下面是MyClassLoader的代码:
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class MyClassLoader extends ClassLoader {
public MyClassLoader() {
} public Class<?> findClass(String name) throws ClassNotFoundException {
String classPath = MyClassLoader.class.getResource("/").getPath();
String fileName = name.replace(".", "/") + ".class";
File classFile = new File(classPath, fileName);
if(!classFile.exists()) {
throw new ClassNotFoundException(classFile.getPath() + " 不存在");
} else {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteBuffer bf = ByteBuffer.allocate(1024);
FileInputStream fis = null;
FileChannel fc = null; try {
fis = new FileInputStream(classFile);
fc = fis.getChannel(); while(fc.read(bf) > 0) {
bf.flip();
bos.write(bf.array(), 0, bf.limit());
bf.clear();
}
} catch (FileNotFoundException var20) {
var20.printStackTrace();
} catch (IOException var21) {
var21.printStackTrace();
} finally {
try {
fis.close();
fc.close();
} catch (IOException var19) {
var19.printStackTrace();
} } return this.defineClass(bos.toByteArray(), 0, bos.toByteArray().length);
}
}
}
java中的动态加载和热替换的更多相关文章
- 透过现象看本质:Java类动态加载和热替换
摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...
- 浅析java中ClassLoader如何加载Class
我的博客地址:https://blog.csdn.net/qq_41907991 ClassLoader是一个经常出现又让很多人望而却步的词.本文试图以最浅显易懂的方式来讲解ClassLoader,希 ...
- 解决tableView中cell动态加载控件的重用问题
解决tableView中cell动态加载控件的重用问题 tableView的cell,有时候需要在运行时取得对应的数据后才能够动态的创建该cell中的控件并加载到该cell中,此时,你一定会遇到重用问 ...
- java——Class、动态加载
Class和Object混淆了? Object: 任何类都是Object类的子类 Class: 任何类都是Class的实例对象 Class可以说是一种特殊的类,它表示的是类类型,Object仍然是Cl ...
- Android中的动态加载机制
在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...
- Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)
需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现 反射的过程如下: 第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...
- Java运行时动态加载类之ClassLoader
https://blog.csdn.net/fjssharpsword/article/details/64922083 *************************************** ...
- Java实现窗体动态加载磁盘文件
在使用图形界面操作系统时,当打开一个文件夹系统会自动列出该文件夹下的所有文件及子文件夹.本实例实现了类似的功能:首先让用户选择一个文件夹,程序会动态列出该文件夹下的所有文件:如果该文件是隐藏文件,就在 ...
- 通过源码浅析Java中的资源加载
前提 最近在做一个基础组件项目刚好需要用到JDK中的资源加载,这里说到的资源包括类文件和其他静态资源,刚好需要重新补充一下类加载器和资源加载的相关知识,整理成一篇文章. 理解类的工作原理 这一节主要分 ...
随机推荐
- 通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。错误:“Connection refused: connect。
查看:http://blog.csdn.net/simunlin/article/details/71123279
- 【Algorithm】回溯法与深度优先遍历的异同
1.相同点: 回溯法在实现上也是遵循深度优先的,即一步一步往前探索,而不像广度优先那样,由近及远一片一片地扫. 2.不同点 (1)访问序 深度优先遍历: 目的是“遍历”,本质是无序的.也就是说访问次序 ...
- 【Smali】Smali文件的动态调试
1.简介 smalidea是一个IntelliJ IDEA/Android Studio smali语言插件,可实现动态调试smali代码.下载地址为:https://github.com/Jesus ...
- 【java】java开发中的23种设计模式详解
设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...
- SpringMVC整合Mongodb开发,高级操作
开发环境: 操作系统:windows xpMongodb:2.0.6依 赖 包:Spring3.2.2 + spring-data-mongodb-1.3.0 + Spring-data-1.5 + ...
- MySQL -- innodb中cardinality是如何统计的
cardinality是放在mysql存储引擎层进行的.采用的是采样取值.在innodb存储引擎中,cardinality统计信息的更新发生在两个操作中:insert和update 更新策略为:-表中 ...
- Linux下Socket网络编程
什么是Socket Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程, ...
- python标准库介绍——34 commands 模块详解
==commands 模块== (只用于 Unix) ``commands`` 模块包含一些用于执行外部命令的函数. [Example 3-7 #eg-3-7] 展示了这个模块. ====Exampl ...
- Nginx(五):浏览器本地缓存设置
浏览器缓存(BrowserCaching) 浏览器缓存是为了加速浏览,浏览器在用户磁盘上,对最近请求过的文档进行存储.当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样,就可以加速页面的 ...
- POJ 3216 Repairing Company(最小路径覆盖)
POJ 3216 Repairing Company id=3216">题目链接 题意:有m项任务,每项任务的起始时间,持续时间,和它所在的block已知,且往返每对相邻block之间 ...