Java类加载器

来源:互联网 发布:excel建模及数据分析 编辑:程序博客网 时间:2024/06/01 07:56

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;}@Overrideprotected 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/
http://www.cnblogs.com/zhguang/p/3154584.html
http://blog.csdn.net/gjanyanlig/article/details/6818655


5.其他

这方面的基础确实比较薄弱,后期再慢慢补充吧!



1 0
原创粉丝点击