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

一、概念

类的加载指的是将类的.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虚拟机系列

JVM学习二:JVM之类加载器之加载分析的更多相关文章

  1. jvm学习笔记之class文件的加载、初始化

    编写的java文件在要真正运行时,会首先被编译成 “.class"结尾的二进制文件,然后被虚拟机加载.那么在虚拟机中一个class文件要成为java实例,需要经历好几个步骤: 1.装载:装载 ...

  2. JVM学习笔记(四):类加载机制

    虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 一.类加载的时机1. 类从被加载到虚拟机内存 ...

  3. JVM自定义类加载器加载指定classPath下的所有class及jar

    一.JVM中的类加载器类型 从Java虚拟机的角度讲,只有两种不同的类加载器:启动类加载器和其他类加载器. 1.启动类加载器(Boostrap ClassLoader):这个是由c++实现的,主要负责 ...

  4. 【JVM学习笔记】系统类加载器

    可以通过“java.system.class.loader"属性指定系统类加载器 默认情况下,该属性值为空: public class Test { public static void m ...

  5. jvm系列一、java类的加载机制

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

  6. JVM规范系列第5章:加载、链接与初始化

    加载是根据特定名称查找类或接口类型的二进制表示(Binary Representation),并由此二进制表示创建类或接口的过程. 加载,就是指去寻找类或接口的过程. 链接是为了让类或接口可以被 Ja ...

  7. JVM系列【3】Class文件加载过程

    JVM系列笔记目录 虚拟机的基础概念 class文件结构 class文件加载过程 jvm内存模型 JVM常用指令 GC与调优 Class文件加载过程 JVM加载Class文件主要分3个过程:Loadi ...

  8. java类加载器加载文件

    例子:采用配置文件加反射的方式创建ArrayList和HashSet的实例对象. //第一种方式:类加载器加载文件 InputStream ips = ReflectTest2.class.getCl ...

  9. Yaf零基础学习总结5-Yaf类的自动加载

    Yaf零基础学习总结5-Yaf类的自动加载 框架的一个重要功能就是类的自动加载了,在第一个demo的时候我们就约定自己的项目的目录结构,框架就基于这个目录结构来自动加载需要的类文件. Yaf在自启动的 ...

随机推荐

  1. 【转】node.js框架比较

    我偶然间看到这篇文章,转这个文章并没有什么含义,仅仅是感觉总结的不错,对于新学node的友友们来说希望这篇文章为大家对 Node.js 后端框架选型带来一些帮助,学习不再迷茫,也是让我有个保存,以后参 ...

  2. 转 从红帽、GitHub和Docker看开源商业模式的进阶

    从红帽.GitHub和Docker看开源商业模式的进阶 发表于2014-12-16 10:26| 7594次阅读| 来源http://stratechery.com/| 0 条评论| 作者Ben Th ...

  3. 简单的 php 防注入、防跨站 函数

    /** * 简单的 php 防注入.防跨站 函数 * @return String */ function fn_safe($str_string) { //直接剔除 $_arr_dangerChar ...

  4. mybatis(一)MyBatis Generator

    在gradle中使用MyBatis Generator时,build.gradle配置如下: dependencies { mybatisGenerator group: 'org.mybatis.g ...

  5. 第115天:Ajax 中artTemplate模板引擎(一)

    一.不分离与分离的比较 1.前后端不分离,以freemarker模板引擎为例,看一下不分离的前后端请求的流程是什么样的? 从上图可以看出,前后端开发人员的工作耦合主要在(3)Template的使用.后 ...

  6. 【bzoj5099】[POI2018]Pionek 双指针法

    题目描述 给你 $n$ 个平面向量,选出它们中的一部分,使得它们的和的长度最大.求这个最大长度的平方. 输入 第一行包含一个正整数n(n<=200000),表示指令条数. 接下来n行,每行两个整 ...

  7. 超链接提示效果jQuery+CSS+html

    我们知道浏览器自带了超链接提示, 只需要在超链接中加入 title 属性就可以了. <a href="#" title="吉大砍人案致1死1伤 受害者死前大喊他手里 ...

  8. 【Java】数据库查询的数据直接以指定文件类型下载到本地(弹出下载框)

    欲实现的功能目标:当点击下图的导出数据文件时弹出文件下载框,默认csv格式,用户自定义下载的本地路径 遇到的问题: 1.项目之前做过一次下载,但是是使用了本地文件模板.用输入流读取文件模板,插入数据, ...

  9. 用Racket语言写了一个万花筒的程序

    用Racket语言写了一个万花筒的程序 来源:https://blog.csdn.net/chinazhangyong/article/details/79362394 https://github. ...

  10. Wifi密码破解实战

    原文链接地址:http://www.freebuf.com/articles/wireless/127261.html https://www.baidu.com/?tn=98012088_4_dg& ...