Java的类加载器自从JDK1.2开始便引入了一条机制,叫做父类委托机制。也就是说,一个类需要被加载的时候,
JVM先会调用他的父类加载器进行加载。如果父类加载器加载不了,再使用其子类进行加载。当然,这类所说的父类加
载器,不一定他们之间是继承的关系,有可能仅仅是包装的关系。不能片面理解。
Java之所以出现这条机制,因为是处于安全性考虑。害怕用户自己定义class文件然后自己写一个类加载器来加载
原本应该是JVM自己加载的类。这样会是JVM虚拟机混乱或者说会影响到用户的安全。
下面我们来自己实现一个类加载器,其中主要就是继承ClassLoader类
package com.bird.classLoad;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class MyClassLoader extends ClassLoader {
private String name; // 类加载器的名字
private String path = "d://"; // 加载类的路径
private final String fileType = ".class"; // .class文件扩展名
public MyClassLoader(String name) {
super();// 让系统加载器成为该类的加载器的父类加载器
this.name = name;
}
public MyClassLoader(ClassLoader parent, String name) {
super(parent); // 显示指定该类加载器的父加载器
this.name = name;
}
@Override
public String toString() {
return this.name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
/**
* 读取class文件作为二进制流放入到byte数组中去
* @param name
* @return
*/
private byte[] loadClassData(String name) {
InputStream in = null;
byte[] data = null;
ByteArrayOutputStream baos = null;
try {
name = name.replace(".", "\\");
in = new BufferedInputStream(new FileInputStream(new File(path
+ name + fileType)));
baos = new ByteArrayOutputStream();
int ch = 0;
while (-1 != (ch = in.read())) {
baos.write(ch);
}
data = baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return data;
}
/**
* JVM调用的加载器的方法
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] data = this.loadClassData(name);
return this.defineClass(name, data, 0, data.length);
}
public static void main(String[] args) throws Exception {
MyClassLoader loader1 = new MyClassLoader("loader1");
loader1.setPath("d://");
test(loader1);
}
public static void test(ClassLoader loader) throws Exception{
Class<?> clazz = loader.loadClass("com.bird.classLoad.Simple");
Object object = clazz.newInstance();
}
}
protected Class<?> findClass(String name) 这个方法是JVM自己调用的,如果覆盖CLassLoader类,必须覆盖这个方
法才能实现类的加载。然后里面的private byte[] loadClassData(String name) 方法是加载class文件变成二进制文件,
以便加载器完成class的引用。
分享到:
相关推荐
自定义类加载器实现自定义加载。自定义类加载器实现自定义加载
主要介绍了Java基于自定义类加载器实现热部署过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
3-7Tomcat中自定义类加载器的使用与源码实现(1).mp4
主要介绍了Java实现的自定义类加载器,结合具体实例形式分析了java自定义类加载器的原理与具体实现技巧,需要的朋友可以参考下
3-7Tomcat中自定义类加载器的使用与源码实现(2).mp4
java,自定义加载类的实现。1.自定义加载类的实现。2双亲委派的验证。3如何制定父类加载器。
简单的对于DirectWrite字体读取接口的实现,通过传入std::vector以获取IDWriteFontCollection.
通过DexClassLoader类加载器来解析优化前面的dex文件 通过DexClassLoader的loadClass函数来载入类 通过获得到的类的newInstance函数来生成需要的对象 开始使用获取到的动态类对象~\(≧▽≦)/~啦啦啦
以下分几个步骤说明自定义监听器实现和使用(以自定义类MyClass加载完成监听器为例): 一、自定义监听器的实现: 1、 定义一个加载完成监听接口 //加载监听接口 public static interface LoadingListener { ...
CustomSkinLoader这是什么? 适用于Minecraft的自定义皮肤加载... 如果您是皮肤服务器的所有者,则如果服务器已实现其中一种API,则可以使用CustomSkinLoader从服务器加载皮肤。高清皮肤支持即使您没有OptiFine和MCPatc
此外,我们还会探讨Java程序的类加载器和双亲委派机制,以及自定义类加载器和类卸载的实现原理和应用方法。 总的来说,本资源将为Java程序员提供全面的Java字节码和类加载原理和实践经验。通过学习本资源,开发人员将...
自定义类加载器实现类的加载 & 热替换,通过反射实现 main 方法的运行。 解决多用户同时发送执行代码请求时的并发问题: 通过 ThreadLoacl 实现线程封闭,为每个请求创建一个输出流存储标准输出及标准错误结果。 ...
今天小编就为大家分享一篇pytorch 自定义数据集加载方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
自定义CollectionView轮播图,不依赖任何图片加载框架,可实现自定义pageControl,自定义轮播View,自定义滚动样式等等 github地址: https://github.com/gltwy/LTAutoScrollView
自定义地图加载器一个自定义地图加载器,可轻松将自定义地图管理到Rocket League中。 Lethamyr(许多自定义地图的创建者)极大地实现了所有这些地图,都可以从下载。 最新版本将在此处发布,该应用程序将自动更新。
gilde 自定义gif解码器 解决太多gif导致cup占用率高,使用第android 7.0上的FrameSequenceDrawable 实现
PowerMock使用一个自定义类加载器和字节码操作来模拟静态方法,构造函数,final类和方法,私有方法,去除静态初始化器等等。通过使用自定义的类加载器,简化采用的IDE或持续集成服务器不需要做任何改变。熟悉...
比较行的自定义NavigationController,抛弃隐藏原生NavigationBar,使用自定义View的方式,通过修改视图的加载,已经对原生方法的重写,达到与原生一样的业务跳转,代码部分参考JTNavigationController,和...
Spring AOP的实现机制中文版,动态代理及原理,自定义类加载器