您的位置:首页 > 编程语言 > Java开发

Java类加载器

2015-12-07 22:32 399 查看

1.类加载的简单过程

Java虚拟机通过javac将.java文件编译成.clas字节码s的文件,而类加载器加载.class字节码文件进内存中

1.1类加载器的层次机构

引导类加载器 (一般用c语言来实现) --》 rt.jar

扩展类加载器 --》 jre/lib/ext

系统类加载器 --》CLASSPATH

备注:类加载器中有一种父子关系,除了引导类加载器外,每个类加载器都有一个父类加载,根据JAVA规范类加载会为它的父类提供一个机会,以便加载任何给定的类,并且只有再其父类加载器加载失败是,它才会加载该给定类。

通常情况下,你不必关心类加载器的层次结构,当你需要干涉指定类加载器是你可以调用Class.forName(String className);

JDK原生类加载器:

java.lang.ClassLoader

2.类加载的三个过程

2.1类装载(即上一个步骤所说的)

public Class<?> loadClass(String name) throws ClassNotFoundException


2.2链接

protected final void resolveClass(Class<?> c)


2.3初始化

2.4 例子MyProgram.class运行,jvm执行步骤(来自JAVA 核心技术 卷2 高级特效)

2.4.1上下文加载器(这里指系统类加载器)从磁盘上读取.class字节码文件,并通过defineClass实例化该类

2.4.2如果MyProgram类拥有另一个类的实例变量,或者是拥有超类,那么这些类文件也会被加载(加载某各类所依赖的所有类的过程叫做类的解析)

2.4.3虚拟机执行MyProgram中的main方法(它是静态的,无需创建类的实例)

2.4.4如果main方法需要用到更多的类,那么接下来会加载这些类

备注:以上的只是大致的步骤,当然细节还有多内容,可以查看目录4:其他优秀资源

3.开发自己的类加载器

只需继承超类ClassLoader的fildClass方法即可,原因参考1.1备注
package com.ccy.classLoader;

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 fileDir;

public MyClassLoader(String fileDir) {
this.fileDir = fileDir;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = getClassData(name);
if (classData == null) {
throw new ClassNotFoundException();
}
else {
//把字节码转换成 java.lang.Class类的实例
return defineClass(name, classData, 0, classData.length);
}
}

//将.class文件读取都内存中
private byte[] getClassData(String className) {
String path = classNameToPath(className);
try {
InputStream ins = new FileInputStream(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
int bytesNumRead = 0;
while ((bytesNumRead = ins.read(buffer)) != -1) {
baos.write(buffer, 0, bytesNumRead);
}
return baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

private String classNameToPath(String className) {
return fileDir + File.separatorChar
+ className.replace('.', File.separatorChar) + ".class";
}

}


4.参考(其他优秀资源):

https://www.ibm.com/developerworks/cn/java/j-lo-classloader/

/article/6983765.html

/article/8093952.html

5.其他

这方面的基础确实比较薄弱,后期再慢慢补充吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: