JAVA 类加载器讲解
【摘要】 一、前言今天我们讲类加载机制5个阶段中的第一个阶段,加载,又叫装载。为了便于阅读,以下都叫做装载。装载的第一步就是要获得二进制的字节流,它可以从读.class文件获得,也可以从网络中接收别人发送的字节流。反正只要符合虚拟机规定的字节流格式都可以进入这个阶段。有了字节流之后,要进行装载还需要一个工具,那就是加载器了。加载器既可以使用系统提供的引导类加载器,也可以使用用户自己定义的加载器,只需...
一、前言
今天我们讲类加载机制5个阶段中的第一个阶段,加载,又叫装载。为了便于阅读,以下都叫做装载。
装载的第一步就是要获得二进制的字节流,它可以从读.class
文件获得,也可以从网络中接收别人发送的字节流。反正只要符合虚拟机规定的字节流格式都可以进入这个阶段。
有了字节流之后,要进行装载还需要一个工具,那就是加载器了。加载器既可以使用系统提供的引导类加载器,也可以使用用户自己定义的加载器,只需要继承ClassLoader
,再重写loadClass()
方法就可以实现一个自己的简单加载器。
像上面的代码那样,就是一个简单的类加载器。当我们要自己加载某个类的时候,就可自己调用loadClass
方法,参数通常为要加载类的全类名,再根据name
获得文件,得到字节流后便可加载,示例代码如下:
public class Test extends ClassLoader{
@Override
public Class<?> loaderClass(String name) throws ClassNotFoundException {
// 获得.class文件的名称
String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
try {
InputStream is = new FileInputStream(fileName); // 获得字节流
if(is == null) { // 若为空,就调用父类加载器
return super.loadClass(name);
}
byte b[] = new byte[is.available()];
is.read(b); //将字节流全部读进字节数组
// 进入接下来的阶段
return defineClass(name, b, 0, b.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return super.loadClass(name);
}
一般的工作情况下我们不会自己去实现加载器,都是采用系统默认的加载器。绝大部分Java
程序都会使用到系统提供的以下3种加载器:
Bootstrap ClassLoader
:启动类加载器。负责加载JAVA_HOME/lib/
里所有能被虚拟机识别的类(如:rt.jar)。无法被Java
程序直接引用,由C++
实现,不是ClassLoader
子类。Extension ClassLoader
:扩展类加载器。负责加载java
平台中扩展功能的一些jar
包,包括JAVA_HOME/lib/ext/
目录中的或java.ext.dirs
系统变量指定目录下的所有类库。是ClassLoad
的子类,开发者可以直接使用该加载器。App ClassLoader
:应用程序类加载器。负责加载classpath
中指定的jar
包及目录中class
。getSystemClassLoader()
的返回值就是该加载器,开发者可以直接使用该加载器。
本篇博文先了解这些知识点,在下篇博文中我们会讲解虚拟机如何运用这些加载进行搭配工作。
对于刚刚上面的代码,小伙伴可以自己尝试着写写。字节流可以读文件,也可以通过网络获得,得到后进行加载,再通过反射执行loadClass()
返回的对象的相关方法。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)