Java-类加载器

 

JAVA加载类说明

当执行某个类的时候, java.exe 会帮助我们找到 JRE ,接着找到位于 JRE 内部的 jvm.dll ,这才是真正的 Java 虚拟机器 , 最后加载动态库,激活 Java 虚拟机器。虚拟机器激活以后,会先做一些初始化的动作,比如说读取系统参数等。一旦初始化动作完成之后,就会产生第一个类加载器―― Bootstrap Loader , Bootstrap Loader 是由 C++ 所撰写而成,这个 Bootstrap Loader 所做的初始工作中,除了一些基本的初始化动作之外,最重要的就是加载 Launcher.java 之中的 ExtClassLoader ,并设定其 Parent 为 null ,代表其父加载器为 BootstrapLoader 。然后 Bootstrap Loader 再要求加载 Launcher.java 之中的 AppClassLoader ,并设定其 Parent 为之前产生的 ExtClassLoader 实体。这两个加载器都是以静态类的形式存在的。这里要请大家注意的是, Launcher$ExtClassLoader.class 与 Launcher$AppClassLoader.class 都是由 Bootstrap Loader 所加载,所以 Parent 和由哪个类加载器加载没有关系。

加载器对应的系统参数如下:

BootstrapLoader : sun.boot.class.path

ExtClassLoader:      java.ext.dirs

AppClassLoader:      java.class.path

执行java XXX.class的过程

找到JRE——》找到jvm.dll——》启动JVM并进行初始化——》产生Bootstrap Loader——》载入ExtClassLoader——》载入AppClassLoader——》执行java XXX.class

加载类工作原理

加载类采用的是全盘负责委托机制(双亲委托)。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入;委托机制则是先让parent(父)类加载器 (而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。此外类加载还采用了cache机制,也就是如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么我们修改了Class但是必须重新启动JVM才能生效的原因。

加载类*.class过程

AppClassLoader 要载入*.class时,首先请求其Parent ClassLoader,也就是ExtClassLoader 来载入,而ExtClassLoader 又请求其Parent ClassLoader,即Bootstrap Loader 来载入Class。如果找到*.class,则加载,如果Bootstrap Loader 无法在其搜寻路径下找到,则由ExtClassLoader 在其搜寻路径下查找该类,如果找到就加载,找不到的话,最后只好由AppClassLoader 在自己搜寻路径底下查找,如果找到*.class,则加载,否则报异常。

测试类加载路径和父加载器的示例代码

import java.net.URL;
import java.net.URLClassLoader;
public class ClassTest {
 public static void main(String[] args) {
        System.out.println("-------------------------------------");
        System.out.println(System.getProperty("sun.boot.class.path"));
        URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
        for (int i = 0; i < urls.length; i++) {
          System.out.println(urls[i].toExternalForm());
        }
        System.out.println("-------------------------------------");
        System.out.println(System.getProperty("java.ext.dirs"));
        ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();
        System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
        System.out.println("extension classloader can use thess jars:");
        URL[] extURLs = ((URLClassLoader)ClassLoader.getSystemClassLoader().getParent()).getURLs();
        for (int i = 0; i < extURLs.length; i++) {
               System.out.println(extURLs[i]);
        }
        System.out.println("-------------------------------------");
        System.out.println(System.getProperty("java.class.path"));
        ClassLoader systemClassloader=ClassLoader.getSystemClassLoader();
        URL[] dd = ((URLClassLoader)ClassLoader.getSystemClassLoader()).getURLs();
        for (int i = 0; i < dd.length; i++) {
               System.out.println("*********  "+dd[i]);
        }
        System.out.println("the parent of system classloader : "+systemClassloader.getParent());
 }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值