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中的动态加载和热替换的更多相关文章

  1. 透过现象看本质:Java类动态加载和热替换

    摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...

  2. 浅析java中ClassLoader如何加载Class

    我的博客地址:https://blog.csdn.net/qq_41907991 ClassLoader是一个经常出现又让很多人望而却步的词.本文试图以最浅显易懂的方式来讲解ClassLoader,希 ...

  3. 解决tableView中cell动态加载控件的重用问题

    解决tableView中cell动态加载控件的重用问题 tableView的cell,有时候需要在运行时取得对应的数据后才能够动态的创建该cell中的控件并加载到该cell中,此时,你一定会遇到重用问 ...

  4. java——Class、动态加载

    Class和Object混淆了? Object: 任何类都是Object类的子类 Class: 任何类都是Class的实例对象 Class可以说是一种特殊的类,它表示的是类类型,Object仍然是Cl ...

  5. Android中的动态加载机制

    在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优势.本 ...

  6. Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)

    需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现   反射的过程如下:     第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...

  7. Java运行时动态加载类之ClassLoader

    https://blog.csdn.net/fjssharpsword/article/details/64922083 *************************************** ...

  8. Java实现窗体动态加载磁盘文件

    在使用图形界面操作系统时,当打开一个文件夹系统会自动列出该文件夹下的所有文件及子文件夹.本实例实现了类似的功能:首先让用户选择一个文件夹,程序会动态列出该文件夹下的所有文件:如果该文件是隐藏文件,就在 ...

  9. 通过源码浅析Java中的资源加载

    前提 最近在做一个基础组件项目刚好需要用到JDK中的资源加载,这里说到的资源包括类文件和其他静态资源,刚好需要重新补充一下类加载器和资源加载的相关知识,整理成一篇文章. 理解类的工作原理 这一节主要分 ...

随机推荐

  1. 【总结】selenium webdriver 远程连接firefox和IE 环境搭建

    参考链接:http://code.google.com/p/selenium/wiki/Grid2 本地环境为:win7,eclipse,jdk 1.7,本机ip为192.168.0.30 1.下载所 ...

  2. 使用libmagic确定文件MIME类型【示例】【转】

    原文地址:http://blog.csdn.net/vevenlcf/article/details/46122661 使用libmagic确定文件MIME类型[示例] 引用:   <http: ...

  3. Word2Vec中文语料实战

    http://blog.csdn.net/gnehcuoz/article/details/52136371

  4. zabbix v3.0安装部署

    这篇文章没有写明init的部分要注意 zabbix v3.0安装部署 摘要: 本文的安装过程摘自http://www.ttlsa.com/以及http://b.lifec-inc.com ,和站长凉白 ...

  5. 把PHP的数组变成带单引号的字符串

    上次做项目的时候,遇到 查询结果为 数组.因为条件原因,需要用$where['_string'] 去组合查询.进而用到把数组变成单引号的字符串.举例:查询返回的数组为: $projectcode_ar ...

  6. iscsi target 之LIO配置

    LIO 配置 现在主流Linux都可以设置iSCSI,如STGT/TGT.LIO Target等.Linux-IO(LIO)Target是当前Linux标准的iSCSI target的开源实现,包含在 ...

  7. 定制jQuery File Upload为微博式单文件上传

    日志未经声明,均为AlloVince原创.版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可. jQuery File Upload是一个非常优秀的上传组件,主要使用了XHR作为上传方 ...

  8. Kibana常用命令

    一.范围(>500) totalTime: [500 TO *] 二.不等于 NOT monitorName: "XXX" 三.字符匹配 正则表达式:    +url:/.* ...

  9. c# 中内部类的简单介绍 C#内部类

    最近在看java一方面的书籍,看到一个很奇怪的问题,java类中还可以再定义一个类,这种结构非常特殊!后来才发现我知识浅薄了,原来C#中也有内部类,之前都一直没有注意过这个语法结构! 使用内部类有这样 ...

  10. Python之杨辉三角算法实现

    学习了廖雪峰的官方网站的python一些基础,里面有个题目,就是让写出杨辉三角的实现,然后我就花了时间实现了一把.思路也很简单,就是收尾插入0,然后逐层按照杨辉三角的算法去求和实现杨辉三角. 附属代码 ...