JVM学习二:JVM之类加载器之加载分析

前面一遍,我们对类的加载有了一个整体的认识,而这一节我们细节分析一下类加载器的第一步,即:加载。

                                             

一、概念

类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。

加载.class文件的方式:
  1.从本地系统中直接加载
  2.通过网络下载.class文件
  3.从zip,jar等归档文件中加载.class文件
  4.从专有数据库中提取.class文件
  5.将Java源文件动态编译为.class文件

类的加载的最终产品是位于堆区中的Class对象。
Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

 

二、加载器分类

类的加载器有两种:
1、Java虚拟机自带的加载器
2、用户自定义类加载器
而Java虚拟机自带的加载器又包括3种类加载器:
1.根类加载器(Bootstrap)
2.扩展类加载器(Extension)
3.系统类加载器(Ststem)
系统类加载器又称为应用类加载器
其中扩展类加载器和系统类加载器是使用Java实现的。而根加载器是使用C++实现的,JVM的API也没有暴露根类加载器,程序员无法在Java代码中获取根加载器。用户自定义类加载器是用户自己写的类加载器,但是必须继承java.lang.ClassLoader这个类,用户可以自定义类的加载方式!
我们先来看下类加载器的相关API

 

 

每个Class对象都包含了一个对定义的Classloader的定义,也就是说通过Class我们可以拿到对应的Classloader,那我们再来看一下Class这个对象如何拿到Classloader。

Class对象有一个getClassLoader的方法用于返回该类的类加载器,但有些实现可能使用null来标识引导类加载器(根类加载器)。也就是说当我们使用根加载器加载的对象使用此方法获取到的ClassLoader是null,为什么是这样呢?前面我们也已经说了,根类加载器是使用C++编写的,JVM不能够也不允许程序员获取该类,所以返回的是null,下面还有一句,如果此对象表示的是一个基本类型或void,则返回null,其实进一步的含义就是:Java中所有的基本数据类型都是由根加载器加载的!(JDK1.5以后将void纳入为基本数据类型)!

下面我们通过代码来具体来看一下类的相关加载器!(看下面一段代码)

public class ClassLoaderTest {


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

       System.out.println(Class.forName("java.lang.String").getClassLoader());

    }

}

刚才我们已经说了,基本数据类型使用根类加载器加载的,因此本类中java.lang.String获取类加载器返回的结果应该是null。运行结果如下:

 

查看自定义的类加载器:

public class ClassLoaderTest {

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

    System.out.println(Class.forName("com.jvm.classloader.test.ClassLoaderTest").getClassLoader());

    }

}

我们可以看到运行结果是AppClassLoader执行的,即应用类加载器(系统类加载器)! 那么什么时候加载,即加载时机是?

三、加载时机

通过上面我们了解了类加载器之加载,也知道了其分类,那么到底什么时候加载呢?

类的加载时机:所有的类或接口都是在Java虚拟机首次“主动使用”的时候才会初始化(初始化章节分析),类从class文件到内存经过了“加载”、“连接”、“初始化”,类是在首次主动使用的时候进行初始化,那他是什么时候加载的呢?

类的加载并不需要到该类或接口被首次主动使用的时候才加载,JVM规范允许类加载器在预料到某个类将要被使用时就预先加载它,如果在预先加载工程中遇到了.class文件缺失或存在错误,则类加载器必须在程序主动使用该类的时候报告LinkageError错误,如果这个类一直没有被程序主动使用,则该类加载器不会报告错误!即使不存在这个类也不会报告错误!

 

参考资料:

 圣思园张龙老师深入Java虚拟机系列

posted on 2018-03-24 20:01  pony1223  阅读(712)  评论(0编辑  收藏  举报

导航