赞
踩
编写好 Java 源码 Student.java ,
使用 javac 将上述 Java 源码编译成 Class 字节码文件 Student.class ,
加载 : 通过 " 类加载子系统 " 将该字节码文件 , 加载到 Java 虚拟机内存中 的 方法区 , 然后开始执行 " 连接 " 操作 ,
类加载时机 : Java 程序执行时 , 并不是一开始将所有的字节码文件都加载到内存中 , 而是用到时才进行加载 ;
连接操作 分为 3 3 3 个步骤 :
0xCAFEBABE
开头 , 字段表 , 方发表 , 属性表 等格式是否正确 , 进行校验 ;1: invokespecial #1
父类构造方法 , 如果父类有有参的构造方法且没有声明无参构造方法 , 子类必须实现一个相同参数的构造方法 , 否则就会报错 ;Constant pool:
#1 = Methodref #4.#17 // java/lang/Object."<init>":()V
{
public Student();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
}
static int a = 5
已经有了赋值 , 但是在该阶段暂时给该静态变量赋值 0
;#1 = Methodref #4.#17
样式的 符号引用 转为 指向内存地址 的 指针引用 ; JVM 线程栈 的 栈帧 中的 动态链接 , 就是持有的一个指向内存的指针 , 该指针指向 栈帧 对应方法 在运行时 常量池中的 内存地址 ; 该内存地址是在 方法区 中的 ;Constant pool:
#1 = Methodref #4.#17 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#18 // Student.name:Ljava/lang/String;
#3 = Class #19 // Student
#4 = Class #20 // java/lang/Object
( 分析的数据是 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 ) 二、字节码文件示例 章节中的 Java 源码 , Class 字节码 , 字节码附加信息 ; )
初始化 : 对变量进行 指定赋值 ;
如 : 有静态变量 static int a = 5
, 在 连接 过程中的 准备 阶段 , 为该变量赋值默认值 0
; 在 初始化 阶段 , 为其赋值 代码 中设置的真正的 指定初始值 5
;
借助下图理解类加载过程 ;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。