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
- 主动使用(七种)
- 创建类的实例
- 访问某个类或接口的静态变量,或者对该静态变量赋值
- 调用类的静态方法
- 反射 (如 Class.forName(“com.test.test”) )
- 初始化一个类的子类
- Java虚拟机启动时被标注为启动类的类(Java Test)
- JDK7 1.7 开始提供的动态语言的支持
4. 类的使用与卸载
- 使用
- 卸载
创建实例项目解释 采取gradle 方式 创建项目
以下代码 会输出什么
案例一
- 说 是不是做错了 我也是 ?,为什么 是因为
还是仔细看
**对于静态字段来说,只有直接定义了该字段的类才会被初始化**
案例二
**初始化一个类的子类**
-XX:+TraceClassLoading 用于追踪类的加载信息并打印出来
- 点击运行
-XX:+ < option> 表示开启 option 选项
-XX:-< option> 表示关闭option选项
-XX:< option>=< value> 表示将option选项的值设置为value
案例三
- 这个是毋庸置疑的
案例四
- 为什么呢?
常量在编译阶段 会存入到 调用这个常量的方法 所在的类的常量池中,
本质上,调用类并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化
**注意** 这里指的将常量存放到了 MyTest01 的常量池中,之后 MyTest01与MyParent1 就没有任何关系了 甚至我们可以将MyParent1 的class文件删除
对结果没有任何影响
-
我们来反编译看一下:
-
此时看出 str 指向的是 字符串 而不是 再从MyParent中取
助记符
- ldc 表示将 int flout 或者String 类型的常量值从常量池中推送至栈顶
- bipush 表示将单字节 (-128 ~ 127)常量值从常量池中推送至栈顶
- sipush 表示将 一个短整型 常量值(-32768 ~ 32767 )推送至栈顶
- iconst_1 表示将int 类型1 推送至栈顶 (iconst_m1 ~iconst_5)( -1 ~ 5)