13 类初始化
2020-05-21 本文已影响0人
陈桐Caliburn
gojvm目录
1、搭建go环境
2、cmd命令行参数解析
3、搜索class文件
4、添加testOption 便于单元测试
5、解析classfile文件
6、运行时数据区
7、指令集
8、解释器
9、创建Class
10、类加载器
11、对象实例化new object
12、方法调用和返回
13 类初始化
14、jvm支持数组
15、jvm支持字符串-数组扩展
16、本地方法调用
17、ClassLoader原理
18、异常处理
19、 启动jvm
类初始化触发情况
1、执行new指令创建类实例
2、执行putstatic、getstatic 指令存取类的静态变量
3、执行invokestatic调用静态方法
4、初始化一个类时,类的超类还没有初始化,要先初始化超类
5、执行某些反射操作
type Class struct{
//其他字段
initStarted bool
}
func (self *Class) InitStarted() bool {
return self.initStarted
}
// setter
func (self *Class) StartInit() {
self.initStarted = true
}
初始化逻辑
在指令 putstatic、getstatic、new、invokestatic 添加初始化逻辑
if !class.InitStarted() {
frame.RevertNextPC()
base.InitClass(frame.Thread(), class)
return
}
func (self *Frame) RevertNextPC() {
self.nextPC = self.thread.pc
}
base逻辑
func InitClass(thread *rtda.Thread, class *heap.Class) {
class.StartInit() // 设置开始初始化标志
scheduleClinit(thread, class) // 准备执行类初始化方法,push到栈顶,下一次执行的时候就会执行<cinit>
initSuperClass(thread, class) // 循环初始化父类
}
func scheduleClinit(thread *rtda.Thread, class *heap.Class) {
clinit := class.GetClinitMethod()
if clinit != nil {
// exec <clinit>
newFrame := thread.NewFrame(clinit)
thread.PushFrame(newFrame)
}
}
func initSuperClass(thread *rtda.Thread, class *heap.Class) {
if !class.IsInterface() {
superClass := class.SuperClass()
if superClass != nil && !superClass.InitStarted() {
InitClass(thread, superClass)
}
}
}