Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >getClassLoader能否为null

getClassLoader能否为null

作者头像
全栈程序员站长
发布于 2022-08-24 12:45:48
发布于 2022-08-24 12:45:48
67400
代码可运行
举报
运行总次数:0
代码可运行

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

前言

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

  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类中,那么我们就去看下这个类的构造器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)这句,那我们就看这个方法是怎么写的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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代码不能直观的获取。

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月9,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
jdk-Launcher源码学习
源码类位置:sun.misc.Launcher、java.lang.ClassLoader
逍遥壮士
2022/04/26
4040
类加载器的双亲委派模型_java mock 模拟接口
看下ExtClassLoader的获取方法getExtClassloader(): 可以看到ExtClassLoader是Launcher的一个内部类,继承的是URLClassLoader。
全栈程序员站长
2022/09/22
8340
类加载器的双亲委派模型_java mock 模拟接口
阅读 Flink 源码前必知必会 - SPI 和 ClassLoader
Java 中的类加载器,是 Java 运行时环境的一部分,负责动态加载 Java 类到 Java 虚拟机的内存中。
kk大数据
2021/02/07
1.4K1
阅读 Flink 源码前必知必会 - SPI 和 ClassLoader
2.双亲委派机制详细解析及原理
研究类加载的过程就是要知道类加载的时候使用了双亲委派机制。但仅仅知道双亲委派机制不是目的,目的是要了解为什么要使用双亲委派机制,他的原理是什么?知道双亲委派机制的逻辑思想,然后这个思想是否可以被我们借鉴,为我所用。这才是学习知识的目的。
用户7798898
2021/10/09
7550
Java类加载器
通过一个类的全限定名来获取描述此类的二进制字节流这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。
@阿诚
2020/09/01
8570
Java类加载器
《Java虚拟机原理图解》5. JVM类加载器机制与类加载过程
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.csdn.net/article/details/50529868
亦山
2019/05/25
1.3K0
Java 能否自定义一个类叫 java.lang.System?
然后随手又刷了几个,基本雷同,看到的博客都是在讲 java 类加载的双亲委托机制, 一个类在需要加载时,会向上委托,直到最上层的 bootstrapClassLoader ,然后最上层的 bootstrapClassLoader 如果能在自己对应的目录加载就加载,不能就向下查找。
江南一点雨
2019/06/01
1.5K0
从JDK源码级别彻底刨析JVM类加载机制
“ 当我们用java命令运行某个类的main函数启动程序时,大家有没有想过是怎样加载的,本文将带着大家一起探讨JVM类的加载机制”
会呼吸的Coder
2022/06/13
3010
从JDK源码级别彻底刨析JVM类加载机制
openjdk使用_深入地理解
  关于JVM类加载的基础理论知识,请参照《深入理解Java虚拟机》读书笔记(六)–虚拟机类加载机制(上)和《深入理解Java虚拟机》读书笔记(六)–虚拟机类加载机制(下)。
全栈程序员站长
2022/09/22
9020
openjdk使用_深入地理解
深入探究JVM之类加载与双亲委派机制
前面学习了虚拟机的内存结构、对象的分配和创建,但对象所对应的类是怎么加载到虚拟机中来的呢?加载过程中需要做些什么?什么是双亲委派机制以及为什么要打破双亲委派机制?
夜勿语
2020/09/07
5050
从源码角度学习JVM类加载器及自定义类加载器
负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,这个加载器是由C++写的,所以我们在java源码里面是找不到它的实现,如果尝试对它进行打印,输出将为空值。
AI码师
2022/12/22
4570
从源码角度学习JVM类加载器及自定义类加载器
jvm类加载机制
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。
Leetcode名企之路
2018/11/29
5300
jvm类加载机制
ClassLoader解惑
一个Java程序要想运行起来,首先需要经过编译生成 .class文件,然后创建一个运行环境(jvm)来加载字节码文件到内存运行,而.class 文件是怎样被加载中jvm 中的就是Java Classloader所做的事情。
加多
2018/09/06
1.5K0
ClassLoader解惑
4. JDK源码级别彻底剖析类加载机制
当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载器把主类加载到 JVM。
源码之路
2021/03/02
4500
4. JDK源码级别彻底剖析类加载机制
从 sun.misc.Launcher 类源码深入探索 ClassLoader
从 深入浅出 ClassLoader 一文中我已经通过大量的理论和示例对ClassLoader有了深入的了解。该文,我们将从 sun.misc.Launcher 源码对 ClassLoader 进行进一步的探索,也是除了示例外的另一个更本质的角度来验证我们之前说的理论。
tomas家的小拨浪鼓
2019/08/06
2.1K0
从 sun.misc.Launcher 类源码深入探索 ClassLoader
Java学习记录--委派模型与类加载器
最近在读许令波的深入分析Java Web技术内幕一书,对于学习Java以来一直有的几个疑惑得到了解答,遂记录下来.
屈定
2018/09/27
6560
Java学习记录--委派模型与类加载器
一文带你深扒ClassLoader内核,揭开它的神秘面纱!
ClassLoader 可以说是 Java 最为神秘的功能之一了,好像大家都知道怎么回事儿 (双亲委派模型好像都都能说得出来...),又都说不清楚具体是怎么一回事 (为什么需要需要有什么实际用途就很模糊了...)。
我没有三颗心脏
2020/09/01
6320
一文带你深扒ClassLoader内核,揭开它的神秘面纱!
Java虚拟机--类加载器源码
类加载器源码分析 下面,我们就来深入的学习下类加载器的源码,看看到底做了哪些事情? 类加载体系 上图呈现是源码级别的类加载体系,ClassLoader是基类,所有的类加载器都需要继承它(启动类加载器除
贾博岩
2018/06/20
8540
JVM-白话聊一聊JVM类加载和双亲委派机制源码解析
其中最核心的方法 loadClass ,其实现我们常说的双亲委派机制 ,我们后面展开。
小小工匠
2021/08/17
2980
Java中常见的类加载器及双亲委派机制的原理
我们在代码里得到类的一个class对象,然后通过它的getClassLoader方法得到一个ClassLoader对象,那么运行一下看看这个ClassLoader对象的名字是什么
全栈程序员站长
2022/07/25
2520
Java中常见的类加载器及双亲委派机制的原理
相关推荐
jdk-Launcher源码学习
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验