当前课程知识点:JAVA程序设计进阶 >  第六章 Java虚拟机 >  6.3 Java虚拟机类加载机制 >  Video

返回《JAVA程序设计进阶》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《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虚拟机

在类加载过程中的

各个阶段的这个情况

我们这一节就介绍到这里

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

第六章 Java虚拟机

-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

第七章 深入集合Collection

-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

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。