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

一、概念

类的加载指的是将类的.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. 软工1816 · Alpha冲刺(8/10)

    团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员1(组长):王彬 过去两天完成了哪些任务 推进前后端各个接口的整合 学习jQuery基本语法,为beta阶段的商铺页面做准备 接下 ...

  2. tomcat配置服务

    1.在server中右键添加tomcat 2.双击tomcat打开配置窗口添加jvm参数 -Doapath="C:\exeye-workspace\exEyeWeb\oadoc"  ...

  3. Windows Forms编程实战学习:第一章 初识Windows Forms

    初识Windows Forms 1,用C#编程 using System.Windows.Forms;   [assembly: System.Reflection.AssemblyVersion(& ...

  4. texbbox,combobox设置属性

    --输入框 $("#xx").textbox('setValue','value');  //设置输入框的值 $('#xx').textbox('textbox').attr('r ...

  5. 【Linux】- 简明Vim练习攻略

    vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...

  6. 详解Python闭包,装饰器及类装饰器

    在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...

  7. 51nod-1220-约数之和

    题意 求 \[ \sum _{i=1}^n\sum _{j=1}^nd(ij) \\ d(x)=\sum _{e|x}e \] \(n\le 10^9\) . 分析 没有推出来.这题有几个要点要学习. ...

  8. java实现PV操作

    package com.jayfulmath.designpattern.command; import java.util.concurrent.Semaphore; /* P(S): ①将信号量S ...

  9. 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。

    给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: "bab" 注意: &quo ...

  10. Luogu4926 倍杀测量者(二分答案+差分约束)

    容易想到二分答案.问题变为判断是否所有条件都被满足,可以发现这是很多变量间的相对关系,取个log之后就是经典的差分约束模型了.特殊的地方在于某些人的分数已被给定,从每个人开始跑一遍最短路判断一下是否能 ...