Java 类加载机制

来源:互联网 发布:幻想神域攻略软件 编辑:程序博客网 时间:2024/06/02 03:51

java虚拟机类加载器
加载步骤:
1. 虚拟机有一个用于类加载的机制,用于从数据源中读取类文件,这个源可以是磁盘文件或者web上的文件,这里假设要加载的类是A。
2. 如果A这个类拥有类型为其他类的实例或者是某个类的子类,也就是说它和其他类产生关联或者依赖,那么相关的类也会被加载。
3. 虚拟机执行A中的main方法
4. 如果main方法中有对其他类的依赖,那么加载相应的类。

类加载器:
 

1.启动(Bootstrap)类加载器:引导类装入器是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面的核心类库或-Xbootclasspath选项指定的jar包加载到内存中。**由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

这里写图片描述
这里写图片描述

2.扩展(Extension)类加载器:扩展类加载器是由Sun的ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将< Java_Runtime_Home >/lib/ext或者由系统变量-Djava.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。
3.系统(System)类加载器:系统类加载器是由 Sun的 AppClassLoader(sun.misc.Launcher$AppClassLoader,是URLClassLoader的子类)实现的。它负责将系统类路径java -classpath或-Djava.class.path变量所指的目录下的类库加载到内存中。开发者可以直接使用系统类加载器。

java.lang.ClassLoader中几个重要的方法:

//加载指定名称(包括包名)的二进制类型,供用户调用的接口 public Class<?> loadClass(String name) throws ClassNotFoundException {return loadClass(name, false);} //加载指定名称(包括包名)的二进制类型,同时指定是否解析(但是这里的resolve参数不一定真正能达到解析的效果),供继承用  protected Class<?> loadClass(String name, boolean resolve)        throws ClassNotFoundException{...}//findClass方法一般被loadClass方法调用去加载指定名称类,供继承用  protected Class<?> findClass(String name) throws ClassNotFoundException { … } //定义类型,一般在findClass方法中读取到对应字节码后调用,可以看出不可继承  //(说明:JVM已经实现了对应的具体功能,解析对应的字节码,产生对应的内部数据结构放置到方法区,所以无需覆写,直接调用就可以了)  protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError{ … }  

类加载的层次结构:

这里写图片描述
默认上层优先的结构,除了引导类加载器,其他的类加载器都有一个父类加载器,优先加载父类加载器。例如你要系统类加载器加载一个String类型时,首先系统类加载器,会让他的父亲即扩展类加载器去尝试加载,那么扩展类加载器也会让他的父亲——引导类加载器去尝试加载,引导类加载器是顶层的。

大多数情况下不必担心类加载的层次结构,通常类是由其他的类的需要而被加载的,而这个过程对于大多数人是透明的。

指定加载器:
这里写图片描述
这里写图片描述
这里写图片描述

加载的双亲委派机制:
这里写图片描述
类加载器默认委派关系图
这里写图片描述
这里写图片描述

原创粉丝点击