1. 类加载

  • 在Java 代码中,类型的加载、连接与初始化过程都是在程序期间完成的。
  • 提供了更大的灵活性,增加了更多的可能性。

2. 类加载器 深入剖析

  • Java 虚拟机与程序的生命周期
  • 在如下几种情况下,Java虚拟机将结束生命周期
1.执行了System.exit() 方法
2. 程序正常执行结束
3. 程序在执行过程中遇到了异常或者错误而异常终止
4. 由于操作系统出现错误而导致Java虚拟机进场终止

3. 类的加载 连接 与 初始化

public class Test01 {
    private static int number=1;
}
  • 加载 :查找并加载类的二进制数据
类的加载是指将类的 .class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在内存中创建一个java.lang.Class 对象 (规范并未说明Class对象对于哪里,HotSpot 虚拟机将其放在了方法去中) 用来封装类在方法区内的数据结构
   
   加载  .class 文件的方法
  1. 从本地系统中直接加载
  2. 通过网络下载 .class 文件
  3. 从 zip   jar 等归档文件中加载  .class 文件
  4. 从专有数据库中提取 .class 文件
  5. 将Java 源文件动态白你以为   .class 文件
  • 连接
1. 验证  确保被加载的类的正确性
2. 准备: 为类的**静态变量**分配内存, 并将其初始化**默认值**  (比如此时 number 是 0   )
3. 解析  把类中的 符号引用转换为直接引用 
  • 初始化: 为类的静态变量赋予正确的初始值 (比如此时 number 是1 )
所以number 一开始不是直接被赋值了 1  二十先初始化了默认值 0    再 被赋值 1 
  1. 主动使用(七种)
  • 创建类的实例
  • 访问某个类或接口的静态变量,或者对该静态变量赋值
  • 调用类的静态方法
  • 反射 (如 Class.forName(“com.test.test”) )
  • 初始化一个类的子类
  • Java虚拟机启动时被标注为启动类的类(Java Test)
  • JDK7 1.7 开始提供的动态语言的支持

4. 类的使用与卸载

  • 使用
  • 卸载

JVM - 类的加载 连接 初始化

创建实例项目解释 采取gradle 方式 创建项目

JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化
JVM - 类的加载 连接 初始化
JVM - 类的加载 连接 初始化

以下代码 会输出什么

案例一

JVM - 类的加载 连接 初始化
JVM - 类的加载 连接 初始化

  • 说 是不是做错了 我也是 ????,为什么 是因为
    还是仔细看
    JVM - 类的加载 连接 初始化
**对于静态字段来说,只有直接定义了该字段的类才会被初始化**
案例二

JVM - 类的加载 连接 初始化
JVM - 类的加载 连接 初始化
JVM - 类的加载 连接 初始化

**初始化一个类的子类**

-XX:+TraceClassLoading 用于追踪类的加载信息并打印出来

JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化

  • 点击运行
    JVM - 类的加载 连接 初始化
    JVM - 类的加载 连接 初始化

-XX:+ < option> 表示开启 option 选项

-XX:-< option> 表示关闭option选项

-XX:< option>=< value> 表示将option选项的值设置为value

案例三

JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化

  • 这个是毋庸置疑的
案例四

JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化

  • 为什么呢?
常量在编译阶段 会存入到  调用这个常量的方法 所在的类的常量池中,
本质上,调用类并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化
**注意**  这里指的将常量存放到了 MyTest01 的常量池中,之后 MyTest01与MyParent1  就没有任何关系了  甚至我们可以将MyParent1 的class文件删除

JVM - 类的加载 连接 初始化
对结果没有任何影响

  • 我们来反编译看一下:
    JVM - 类的加载 连接 初始化

  • 此时看出 str 指向的是 字符串 而不是 再从MyParent中取

助记符

  • ldc 表示将 int flout 或者String 类型的常量值从常量池中推送至栈顶
  • bipush 表示将单字节 (-128 ~ 127)常量值从常量池中推送至栈顶
  • sipush 表示将 一个短整型 常量值(-32768 ~ 32767 )推送至栈顶
  • iconst_1 表示将int 类型1 推送至栈顶 (iconst_1 ~iconst_5)

JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化
JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化

JVM - 类的加载 连接 初始化

相关文章: