当前课程知识点:JAVA程序设计进阶 > 第六章 Java虚拟机 > 6.3 Java虚拟机类加载机制 > Video
这一节我们将介绍
Java虚拟机的类加载机制
不知道大家有没有印象
当我们的Java语言程序
编译完了以后
它得到的这个结果
是什么类型的文件
肯定有些同学已经想起来了
那我们一个点Java的语言程序
编完以后就会得到
相应的点class文件
那点class文件
其实就是我们的类文件
有时候我们也称之为
这个字节码文件
那这些字节码文件
在执行的当中
它怎么能够被加载到
Java虚拟机呢
这是我们这节要介绍的内容
我们来看一看虚拟机
类加载机制的一些基本想法
那虚拟机把描述类的数据
从我们的class文件加载到内存
并对数据进行校验
转换 解析和初始化
最终形成可以被虚拟机
直接使用的Java类型
那在Java这个语言的执行过程当中
它有个特别大的一个
好的一个特点
就是我们这种类的加载
和连接过程
是在程序运行期间完成的
那如果大家之前有过一些
比较旧的一些这个编程语言的经验
当我们编译完了以后
可能还要做链接然后再执行
Java它有一个这个大的特点
就是我是在程序运行过程当中
来进行这个类的加载和连接
这样的话就保证了
它这个一个程序运行的
这个流畅和灵活性
那么我们再看一下
我们一个类文件它加载到
我们Java虚拟机的时候
都要经历哪些过程
包括以下这么几个
加载 验证 准备 解析
初始化 使用和卸载
那我们下面马上来具体介绍一下
这几个步骤都是什么含义
首先看一下加载
那加载顾名思义
就是我们把文件系统当中的
某一个点class文件
通过它的这一个它的类名
来去得到它这个类的
二进制的字节码
那我们将这个字节码
所代表的静态的存储结构
把它转换成为我们的方法区
注意 方法区在哪
方法区是刚刚我们上一节介绍过的
Java虚拟机当中的
内存的某一个区域
那我们把我们这个字节码
转换成为方法区的运行时的
数据结构
然后我们就可以在这个
Java的堆中生成一个
代表这个类的class对象
作为方法区这些数据的访问入口
所以这个过程
就是我们的类的加载过程
那当类加载进来的时候
我们还有一个这个要做的事情
就是要验证
那首先验证什么呢
验证这个class文件是不是符合
我们的Java虚拟机的规范
如果它不符合规范的话
我们就要抛出一个
Java.lang.VerifyError
这样的异常
那如果符合虚拟机规范以后
那我们还要做的是
文件格式的验证
也就是说验证
这些字节码是否符合
我们class文件格式的规范
并且能够被当前版本的虚拟机
来进行处理
那经过这个阶段的验证了以后
我们的字节码
就会进入内存的方法区中
进行存储
那紧接着我们还会验证什么
需要验证元数据
也就是说对类的元数据信息
进行语义校验
保证不存在不符合
Java语言规范的元数据信息
紧接着我们再做
字节码的这种验证
那也就是说我们要
进行数据流和控制流的分析
对类的方法体进行校验分析
保证被校验的类的方法
在运行时不会做出
危害Java虚拟机的任何行为
那最后我们还要验证的
是符号引用
那这个验证发生在
虚拟机将符号引用
转换为直接引用的时候
那我们要对常量池中的
各种符号引用的信息
进行匹配性的校验
那这就是我们类加载过程
到虚拟机过程中
验证过程所需要做的事情
那下一个工作的话是准备
那准备阶段是为我们的类变量
大家还记得什么是类变量吗
就是我们用static修饰的变量
它就是类变量
那为这些类变量分配内存
并设置它的初始值的这个阶段
那我们要将这些内存
在方法区当中进行分配
那如果我们类字段的
字段属性表中存在着有
ConstantValue属性
就是常量值属性
那就在这个准备阶段的话
我们这些变量值
就会把它初始成为
ConstantValue属性
所指定的值
那大家看看下面这一行
public static final int value
等于122
那我们可以看出这个value
它是一个整型
同时它又是一个类变量static
另外它又是一个常量final
那给它的赋的值是122
那就这么一行代码在准备阶段
就要把它的相应的这些变量
以及它的值
在我们的方法区内存中进行分配
那下一个这个阶段是解析
那解析阶段是在虚拟机
将常量池内符号引用
替换为直接引用的过程
那符号引用是以一组符号
来描述所引用的目标
那这个符号可以是
任何形式的字面量
只要使用时能够无歧义的
定位到目标就可以了
那符号引用与虚拟机
实现的内存布局无关
引用的目标并不一定是
已经加载到内存当中
另外的话我们也可以
采用直接引用
直接引用可以是
直接指向目标的指针
相对偏移量
或者是一个能间接定位的
到目标的句柄
如果有了直接引用
那引用的目标
必定已经在内存当中已经存在
这个就是我们的解析过程
那再下面一个过程
是一个初始化过程
那初始化过程的话
会涉及到几个方法
那第一个方法叫clinit方法
那实际上这个方法
是由我们的编译器自动收集
一个类当中
所有的类变量的赋值动作
注意类变量就是用static
这个赋值的这个修饰的变量
和静态语句块合并产生
那静态语句块
就是拿一个static
后面跟一段语句块
那这个语句块就是静态语句块
那这个收集的顺序
是由语句在源文件当中
所出现的顺序决定的
那这个是我们clinit方法
它所做的这个事情
当它和我们的实例构造方法init
有所不同
它不需要显示的去调用
父类的构造方法
clinit方法对类或者接口来说
它不是一个必须的
然后我们执行接口的clinit方法
不需要先执行
父接口的clinit方法
那一般说来
虚拟机会保证任何一个类的
clinit方法在多线程环境中
被正确的加锁和同步
那我们下一个阶段是这个
关于就是我们类的主动引用
也就是说我们
当我们的虚拟机
碰到这个new 或者getstatic
putstatic或者invokestatic
这四条字节码指令时候
就是要做这个类的主动引用
new的话实际上指的就是
我们实例化一个对象
而getstatic
就是要读取我们一个
类的静态字段
putstatic它的作用
是设置一个类的静态字段
然后invokestatic的话
是调用一个类的静态方法
那这种类的主动引用方法
我们在使用到Java.lang.reflet包
也就是反射包的时候
会对这个类
进行反射调的时候会用到
这个主动引用
后面我们有专门的一章内容
会讲这个Java类的反射机制
那当我们初始化一个类的时候
如果发现它的父类
还没有进行初始化的话
那就需要先触发
这个父类的初始化的这些方法
那当我们虚拟机启动的时候
虚拟机会初始化主类
什么叫主类
也就是我们类当中
包含main方法的这个类
那这几种情况都是
指的是我们的类的
一种主动引用的情况
那与之相对应的
就是我们的类的被动引用
那什么时候会出现
类的被动引用呢
比如说我们通过子类
引用父类的静态字段
不会导致子类初始化
那我们还可以通过数组
来定义这个类的应用类
比如说我们classA这个
然后一个数组array进行实例化
那它是触发了一个这个
名为这个classA的类的初始化
它由一个虚拟机自动生成
直接继承于Object类
那这种创建动作
由字节码指令newarray
来进行触发
另外的话我们的常量
也会在编译阶段
就会存入调用类的常量值
那关于我们Java虚拟机
在类加载过程中的
各个阶段的这个情况
我们这一节就介绍到这里
-1.0 导学
--Video
-1.1 线程的基本概念
--Video
-1.1 线程的基本概念--作业
-1.2 通过Thread类创建线程
--Video
-1.2 通过Thread类创建线程--作业
-1.3 线程的休眠
--Video
-1.3 线程的休眠--作业
-1.4 Thread类详解
--Video
-1.5 通过Runnable接口创建线程
--Video
-1.5 通过Runnable接口创建线程--作业
-1.6 线程内部的数据共享
--Video
-2.0 导学
--Video
-2.1 线程同步的思路
--Video
-2.2 线程同步的实现方式—Synchronization
--Video
-2.3 线程的等待与唤醒
--Video
-2.4 后台进程
--Video
-2.5 线程的生命周期与死锁
--Video
-2.6 线程的调度
--Video
-3.0 导学
--Video
-3.1 线程安全与线程兼容与对立
--Video
-3.2 线程的安全实现-互斥同步
--Video
-3.3 线程的安全实现-非阻塞同步
--Video
-3.4 线程的安全实现-无同步方案
--Video
-3.5 锁优化
--Video
-4.0 导学
--Video
-4.1 URL对象
--Video
-4.2 URLConnection对象
--Video
-4.3 Get请求与Post请求
--Video
-4.4 Socket通信原理
--Video
-4.5 Socket通信实现
--Video
-5.0 导学
--Video
-5.1 Socket 多客户端通信实现
--Video
-5.2 数据报通信
--Video
-5.3 使用数据报进行广播通信
--Video
-5.4 网络聊天程序
--Video
-6.0 导学
--Video
-6.1 Java虚拟机概念
--Video
-6.2 Java虚拟机内存划分
--Video
-6.3 Java虚拟机类加载机制
--Video
-6.4 判断对象是否存活算法及对象引用
--Video
-6.5 分代垃圾回收
--Video
-6.6 典型的垃圾收集算法
--Video
-6.7典型的垃圾收集器
--Video
-7.0 导学
--Video
-7.1 集合框架与ArrayList
--Video
-7.2 LinkedList
--Video
-7.3 HashMap与HashTable
--Video
-7.4 TreeMap与LinkedHashMap
--Video
-7.5 HashSet
--Video
-8.0 导学
--Video
-8.1 Java反射机制
--Video
-8.2 Java静态代理
--Video
-8.3 Java动态代理
--Video
-8.4 Java 反射扩展-jvm加载类原理
--Video
-8.5 Java进阶课程总结
--Video