一、概述
文件开头有特定的文件标识,将class文件字节码内容加载到内存中,并将这些内容转换成方法去中的运行时数据结构并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由执行引擎(Execution Engine)决定
有没有联想到什么,很可爱有没有?(滑稽脸)
二、虚拟机自带的加载器
1.启动类加载器(根加载器/Bootstrap, 基于C++实现)
在实例化JDK自带的类时就会通过根加载器进行加载,通过代码可以看到这个加载器打印出null,是因为其无法被Java程序直接调用所以在Java中为null(通过根加载器加载会调用findBootstrapClass()方法,这是一个本地方法)。
2.扩展类加载器(Extension,基于Java实现)
扩展类加载器主要用于加载扩展包
扩展包位置位于如图所示:
3.应用程序类加载器(AppClassLoader),Java也叫系统类加载器,加载当前应用的classpath的所有类
在实例我们自定义的类时,将通过AppClassLoader进行加载,如下图所示:
4.各加载器之间的关系
从图中可以看出AppClassLoader是ExtClassLoader的子加载器,而ExtClassLoader是根加载器的子加载器
5.类的加载顺序(加载器角度)
在我们加载一个类首先会在AppClassLoader下验证是否已经加载过此类,如果没有,则会交给父加载器,一直往上推,当根加载器也无法加载此类时,就交由子加载器进行加载,一直到最底层的AppClassLoader,当AppClassLoader也无法加载此类时,就会抛出ClassNotFoundException
Java为什么要提供这种加载类的机制?其实这就是Java类加载中的双亲委派机制
6.双亲委派机制的作用
其最主要的作用是防止开发人员污染JDK,保证Java的安全性,举个例子说明如下图:
这是我自定义的String类,关键在于我把它放在了java.lang包下,根据双亲委派机制JDK自带的类将会在根加载器中进行加载,因此运行此代码将会报错,如图所示,JDK自带的String类并没有main方法。
7.源码欣赏(滑稽脸)
这是类加载中的关键代码loadClass()方法,详情可自行查阅JDK源码。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
以上内容均为个人通过学习后的个人理解,如有不实之处,请各位读者提出,吾必及时改正,非常感谢!