getClassLoader能否为null

getClassLoader能否为null前言我们Javaer都知道类想要被加载是需要一个个ClassLoader来执行的,并且类加载的方案叫双亲委派模式,说是双亲,其实就是单亲,可能我们最初的翻译人想让我们的加载器的家庭更完整吧,所以翻译成双亲。默认的类加载器包括BootstrapClassLoader、ExtClassLoader、AppClassLoader,他们都定义在在rt.jar中的sun….

大家好,又见面了,我是你们的朋友全栈君。

前言

我们Javaer都知道类想要被加载是需要一个个ClassLoader来执行的,并且类加载的方案叫双亲委派模式,说是双亲,其实就是单亲,可能我们最初的翻译人想让我们的加载器的家庭更完整吧,所以翻译成双亲。默认的类加载器包括BootstrapClassLoader、ExtClassLoader、AppClassLoader,他们都定义在在rt.jar中的sun.misc.Launcher类中,他们的”继承”关系是AppClassLoader—>ExtClassLoader—>BootstrapClassLoader,ExtClassLoader的parent获取不到BootstrapClassLoader,只能获取到一个null。

classloader

  1. bootstrap是C++编写的类加载器,主要加载%JRE_HOME/lib/目录下的jar包
  2. ExtClassLoader主要加载%JRE_HOME/lib/ext目录下的jar包
  3. AppClassLoader主要加载java环境变量CLASSPATH所指定的路径下的jar包和class文件,通过System.getProperty(“java.class.path”)获取考验获取CLASSPATH路径
  4. 用户自定义ClassLoader,加载用户自己制定的类

getClassLoader会不会为空

说了这么多,其实就是想说getClassLoader当然可能会为空,是不是此时会有个疑惑:加载器都为空了,那这个类是怎么加载的,被谁加载的?答:被BootstrapClassLoader加载的。

我们知道BootstrapClassLoader是由C++编写的,我们是用Java代码获取不到的,BootstrapClassLoader也不是ExtClassLoader的父类,而是它的父亲,这里要搞清关系,父亲和父类是两码事,父类是有继承关系,父亲是上一层的关系,所以我们在获取String、Integer、int、double、BufferedInputStream等等一系列在rt.jar包中被BootstrapClassLoader加载的类的加载器时,返回的都是null。

ExtClassLoader是怎么成为AppClassLoader的父亲的

类加载器并非是继承关系,而是父子关系,就像上面说的BootstrapClassLoader是ExtClassLoader的父亲,不是父类。关键点就在于ClassLoader的实例变量parent,这个parent指定了当前类加载器的父亲,但是翻遍了AppClassLoader的代码也没发现是在哪里把ExtClassLoader设置进去的,怎么parent就是ExtClassLoader了呢。

刚才我们说这些类加载器被定义在了Launcher类中,那么我们就去看下这个类的构造器

public Launcher() {
  Launcher.ExtClassLoader var1;
  try {
    // 获取ExtClassLoader
    var1 = Launcher.ExtClassLoader.getExtClassLoader();
  } catch (IOException var10) {
    throw new InternalError("Could not create extension class loader", var10);
  }

  try {
    // 获取AppClassLoader实例并赋值给loader,并把ExtClassLoader的实例传入到方法中,
    this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
  } catch (IOException var9) {
    throw new InternalError("Could not create application class loader", var9);
  }
  // ...
}
// 返回AppClassLoader实例
public ClassLoader getClassLoader() {
  return this.loader;
}

从Launcher的构造器我们看到关键点在AppClassLoader.getAppClassLoader(var1)这句,那我们就看这个方法是怎么写的

static class AppClassLoader extends URLClassLoader {
  public static ClassLoader getAppClassLoader(final ClassLoader var0) throws IOException {
    final String var1 = System.getProperty("java.class.path");
    final File[] var2 = var1 == null ? new File[0] : Launcher.getClassPath(var1);
    return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction<Launcher.AppClassLoader>() {
      public Launcher.AppClassLoader run() {
        URL[] var1x = var1 == null ? new URL[0] : Launcher.pathToURLs(var2);
        // 关键看这一句,调用了AppClassLoader的构造器,并把ExtClassLoader实例传了进去,那就跳到构造器去看
        return new Launcher.AppClassLoader(var1x, var0);
      }
    });
  }

  // 构造器
  AppClassLoader(URL[] var1, ClassLoader var2) {
    // 调用了父类的构造器,他的父类是哪个?从定义上看应该是URLClassLoader没跑了
    super(var1, var2, Launcher.factory);
    this.ucp.initLookupCache(this);
  }
}

其实再往里的代码就不用在这闲扯了,里面就是不断的将var2往上传递,直到ClassLoader这个类的构造器中,在ClassLoader中完成的设置。

那为什么ExtClassLoader没通过这种形式将BootstrapClassLoader设置给parent呢?

是不是傻,上面刚说了BootstrapClassLoader是C++写的,Java代码不能直观的获取。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/141668.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 微信小程序轮播图片自适应[通俗易懂]

    微信小程序轮播图片自适应[通俗易懂]微信小程序轮播图片自适应//xml代码<viewclass=”rotation”><swiperclass=”home-swiper”bindchange=”bindchange”style=”height:{{imgheights[current]}}rpx;”><blockwx:for-items=”{{lunboData}}”wx:key=”{{index}}”><swiper-item>

  • 用javascript去掉字符串空格的办法

    今天遇到了以关于JavaScript中怎么去掉字符串中前后两段的空格,我只好向就得js中也后Trim()函数,后来试试了不行,就网上找了下解决方法,其中用到了正则表达式,整理了下:12

    2021年12月21日
  • HTML中设置背景图的两种方式「建议收藏」

    HTML中设置背景图的两种方式「建议收藏」HTML中设置背景图的两种方式1、background  background:url(images/search.png)no-repeattop;2、background-image  background-image:url(images/search.png);  background-repeat:no-repeat;

  • html5 替代css js,jsindexof替代办[通俗易懂]

    html5 替代css js,jsindexof替代办[通俗易懂]js中使用indexOf()方法是提示(对象不支持此属性或js中使用indexOf()方法是提示(对象不支持此属性或方法)解决办法:“对象不支持此属性或方法”表示javascript对象没有这个方法,无法调用,比如A.B()当A对象没有B方法的时候,会报这个异常。因为javascript是脚本语言,解释执行。js中IndexOf()是干什么用的呢?怎么用?varstr=”Hello…

  • 自己整理的运维面试题,必须会。

    自己整理的运维面试题,必须会。1.mysql主从原理。**Slave开启I/O线程来请求master服务器,请求指定bin-logMaster端收到请求,Master端I/O线程响应请求通过bin-log将内容返给salveSlave将收到的内容存入relay-log中继日志中Slave端SQL实时监测relay-log日志有更新执行完毕之后,Slave端跟master端数据保持一致!**2.DNS原理。…

  • LaTex中输入空格以及换行

    LaTex中输入空格以及换行1.使用\表示空格以及调整空格的大小quad空格 a\qquadb 两个m的宽度 quad空格 a\quadb 一个m的宽度 大空格 a\b 1/3m宽度 中等空格 a\;b 2/7m宽度 小空格 a\,b 1/6m宽度 没有空格 ab …

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号