java之jvm学习笔记五(实践写自己的类装载器)
来源:互联网 发布:苹果手机开通4g网络 编辑:程序博客网 时间:2024/06/15 18:35
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao
课程源码:http://download.csdn.net/detail/yfqnihao/4866501
前面第三和第四节我们一直在强调一句话,类装载器和安全管理器是可以被动态扩展的,或者说,他们是可以由用户自己定制的,今天我们就是动手试试,怎么做这部分的实践,当然,在阅读本篇之前,至少要阅读过笔记三。
下面我们先来动态扩展一个类装载器,当然这只是一个比较小的demo,旨在让大家有个比较形象的概念。
第一步,首先定义自己的类装载器,从ClassLoader继承,重写它的findClass方法,至于为什么要这么做,大家如果看过笔记三就知道,双亲委托模式下,如果parent没办法loadClass,bootStrap也没把办法loadClass的时候,jvm是会调用ClassLoader对象或者它子类对象的findClass来装载。
- package com.yfq.test;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- public class MyClassLoader extends ClassLoader {
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- byte[] data = getByteArray(name);
- if (data == null) {
- throw new ClassNotFoundException();
- }
- return defineClass(name, data, 0, data.length);
- }
- private byte[] getByteArray(String name){
- String filePath = name.replace(".", File.separator);
- byte[] buf = null;
- try {
- FileInputStream in = new FileInputStream(filePath);
- buf = new byte[in.available()];
- in.read(buf);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return buf;
- }
- }
第二步,定义一个类,专门用于被装载,这里我们定义了一个静态代码块,待会用到它
- package com.yfq.test;
- public class TestBeLoader {
- static{
- System.out.println("TestBeLoader init");
- }
- public void sayHello(){
- System.out.println("hello");
- }
- }
第三步,定义一个有main函数入口的public类来做验证
- package com.yfq.test;
- public class TestClassLoaderDemo {
- public static void main(String[] args) throws InstantiationException, IllegalAccessException {
- Class thisCls = TestClassLoaderDemo.class;
- MyClassLoader myClassLoader = new MyClassLoader();
- System.out.println(thisCls.getClassLoader());
- System.out.println(myClassLoader.getParent());
- try {
- //用自定义的类装载器来装载类,这是动态扩展的一种途径
- Class cls2 = myClassLoader.loadClass("com.yfq.test.TestBeLoader");
- System.out.println(cls2.getClassLoader());
- TestBeLoader test=(TestBeLoader)cls2.newInstance();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
第四步,查看运行结果
sun.misc.Launcher$AppClassLoader@19821f
sun.misc.Launcher$AppClassLoader@19821f
sun.misc.Launcher$AppClassLoader@19821f
TestBeLoader init
说明:
第一个输出:装载TestClassLoaderDemo的类是AppClassLoder
第二个输出:装载myClassLoader的装载器也是AppClassLoader,这里也验证了我们笔记三讲的,在同个线程中,动态连接模式会运用当前线程的类加载器来加载所需的class文件,因为第一个和第二个输出是同一个对象的对象名
第三个输出:是TestBeLoader的类加载器,这个输出验证了,双亲委托模式下的动态连接模式,由于myClassLoader是由AppClassLoader装载的,所以它会委托自己的parent来装载com.yfq.test.TestBeLoader这个类,加载成功所以就不再调用自己的findClass方法,这个我们在笔记三有做过简要的讨论。
第四个输出:如果我们将TestBeLoader test=(TestBeLoader)cls2.newInstance();这句话注掉,则不会有第四个输出,为什么?
类的装载大致分为三步,装载,连接,初始化。而初始化这一步,是在我们第一次创建对象的时候才进行初始化分配内存,这一点需要注意,并不是class被load内存后就立刻初始化。
- java之jvm学习笔记五(实践写自己的类装载器)
- java之jvm学习笔记五(实践写自己的类装载器)
- java之jvm学习笔记(实践写自己的类装载器)
- java之jvm学习笔记六(实践写自己的安全管理器)
- java之jvm学习笔记六(实践写自己的安全管理器)
- java之jvm学习笔记二(类装载器的体系结构)
- java之jvm学习笔记二(类装载器的体系结构)
- java之jvm学习笔记二(类装载器的体系结构)
- 5.JVM之自己的类装载器
- 《深入java虚拟机--JVM高级特性与最佳实践》学习笔记(一) 编译自己的JDK
- JVM 之 类的装载机制
- JVM java类的装载、链接、初始化
- java之jvm学习笔记八(实践对jar包的代码签名)
- java之jvm学习笔记八(实践对jar包的代码签名)
- java之jvm学习笔记八(实践对jar包的代码签名)
- jvm类装载过程笔记
- JVM 类装载器
- JVM-类装载器
- wxWidgets 学习笔记
- PHP批量发起呼叫--呼叫中心性能测试
- 模拟猜单词游戏
- 怎样学习C语言
- 牛人主页
- java之jvm学习笔记五(实践写自己的类装载器)
- 算法与数据结构面试题(19)-统计字符串中的字符个数
- Android系统的进程,任务,服务的信息
- java+mysql 链接 插入 删除 更新
- Quartz 定时任务
- Sublime 3 破解 + emmet插件包安装 亲身安装测试
- Oracle OLAP 与 OLTP
- android 所遇到的BUG总结
- linux系统管理命令-软件包管理