Java的ClassLoader如何理解

发布时间:2021-11-20 15:04:26 作者:柒染
来源:亿速云 阅读:106

本篇文章为大家展示了Java的ClassLoader如何理解,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

讲解一下 Java 的 ClassLoader。

关于 ClassLoader ,相信大家用的不是很多,但是在面试中可能会被经常问到。所以我这里整理了关于它的一些相关用法。

ClassLoader 是 Java 提供的类加载器,用来加载 Java 类到 Java 虚拟机中的一种加载器。

Java 程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。

JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,BootstrapClassLoader是用本地代码实现的,它负责加载核心JavaClass(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由BootstrapClassLoader加载;其中Extension ClassLoader负责加载扩展的Javaclass(例如所有javax.*开头的类和存放在JRE的ext目录下的类),ApplicationClassLoader负责加载应用程序自身的类。

当运行一个程序的时候,JVM启动,运行bootstrapclassloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。

了解了上面的流程后,我们再通过具体的代码来看看类是如何被加载的。

1

2

3

4

5

6

7

8

9

package com.neo.classloader;

public class ClassLoaderTest {

     public static void main(String[] args) {

        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        System.out.println(loader);

        System.out.println(loader.getParent());

        System.out.println(loader.getParent().getParent());

    }

}

运行后,输出结果:

1

2

3

sun.misc.Launcher$AppClassLoader@64fef26a

sun.misc.Launcher$ExtClassLoader@1ddd40f3

null

从上面的结果可以看出,并没有获取到 ExtClassLoader 的父 Loader,原因是 Bootstrap Loader(引导类加载器)是用C语言实现的,找不到一个确定的返回父 Loader 的方式,于是就返回 null。 这几种类加载器的层次关系如下图所示:

Java的ClassLoader如何理解

注意:这里父类加载器并不是通过继承关系来实现的,而是采用组合实现的。

站在Java虚拟机的角度来讲,只存在两种不同的类加载器:启动类加载器:它使用C++实现(这里仅限于Hotspot,也就是JDK1.5之后默认的虚拟机,有很多其他的虚拟机是用Java语言实现的),是虚拟机自身的一部分;所有其它的类加载器:这些类加载器都由Java语言实现,独立于虚拟机之外,并且全部继承自抽象类java.lang.ClassLoader,这些类加载器需要由启动类加载器加载到内存中之后才能去加载其他的类。

站在Java开发人员的角度来看,类加载器可以大致划分为以下三类:

启动类加载器Bootstrap ClassLoader,负责加载存放在JDK\jre\lib(JDK代表JDK的安装目录,下同)下,或被-Xbootclasspath参数指定的路径中的,并且能被虚拟机识别的类库(如rt.jar,所有的java.开头的类均被Bootstrap ClassLoader加载)。启动类加载器是无法被Java程序直接引用的。
扩展类加载器Extension ClassLoader,该加载器由sun.misc.Launcher$ExtClassLoader实现,它负责加载JDK\jre\lib\ext目录中,或者由java.ext.dirs系统变量指定的路径中的所有类库(如javax.
开头的类),开发者可以直接使用扩展类加载器。
应用程序类加载器Application ClassLoader,该类加载器由sun.misc.Launcher$AppClassLoader来实现,它负责加载用户类路径(ClassPath)所指定的类,开发者可以直接使用该类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

应用程序都是由这三种类加载器互相配合进行加载的,如果有必要,我们还可以加入自定义的类加载器。因为JVM自带的ClassLoader只是懂得从本地文件系统加载标准的java class文件,因此如果编写了自己的ClassLoader,便可以做到如下几点:

JVM类加载机制

类加载有三种方式:

例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package com.xttblog.classloader;

public class loaderTest {

        public static void main(String[] args) throws ClassNotFoundException {

            ClassLoader loader = HelloWorld.class.getClassLoader();

            System.out.println(loader);

            loader.loadClass("Test2");

        }

}

Test2.java

1

2

3

4

5

public class Test2 {

    static {

        System.out.println("静态初始化块执行了!");

    }

}

分别切换加载方式,会有不同的输出结果。

Class.forName()和ClassLoader.loadClass()区别

总结:Java 类的加载机制和ClassLoader看似复杂,实际上却很简单。通过阅读源码或结合运行示例就能更好的理解了。

上述内容就是Java的ClassLoader如何理解,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

推荐阅读:
  1. Java Classloader机制用法代码解析
  2. Java中ClassLoader类加载的示例分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java classloader

上一篇:怎么保护Python代码

下一篇:Python有哪些实用脚本

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》