java new object_11、对象实例化new object

指令

作用

idc

常量池常量推到操作数栈顶

new

新建实例

putfield/getfield

存取实例变量

putstatic/getstatic

存取静态变量

Instanceof/checkcast

判断对象是否属于某类型

public class MyObject {

public static int staticVar;

public int instanceVar;

public static void main(String[] args) {

int x = 32768; // ldc

MyObject myObj = new MyObject(); // new

MyObject.staticVar = x; // putstatic

x = MyObject.staticVar; // getstatic

myObj.instanceVar = x; // putfield

x = myObj.instanceVar; // getfield

Object obj = myObj;

if (obj instanceof MyObject) { // instanceof

myObj = (MyObject) obj; // checkcast

System.out.println(myObj.instanceVar);

}

}

}

关键指令编写

new

func (self *NEW) Execute(frame *rtda.Frame) {

cp := frame.Method().Class().ConstantPool() // 1. 获取当前栈帧所在类的常量池

classRef := cp.GetConstant(self.Index).(*heap.ClassRef) // 2. 获取类符号引用

class := classRef.ResolvedClass() // 3. 根据类符号引用创建类

if !class.InitStarted() {

frame.RevertNextPC()

base.InitClass(frame.Thread(), class)

return

}

if class.IsInterface() || class.IsAbstract() {

panic("java.lang.InstantiationError")

}

ref := class.NewObject() // 4. 创建对象

frame.OperandStack().PushRef(ref) // 5. 将引用对象push到栈顶

}

getstatic

func (self *GET_STATIC) Execute(frame *rtda.Frame) {

cp := frame.Method().Class().ConstantPool()

// 1. 获取字段符号引用

fieldRef := cp.GetConstant(self.Index).(*heap.FieldRef)

// 2. 将字段符号引用解析为Field

field := fieldRef.ResolvedField()

class := field.Class()

if !class.InitStarted() {

frame.RevertNextPC()

base.InitClass(frame.Thread(), class)

return

}

// 不是静态变量

if !field.IsStatic() {

panic("java.lang.IncompatibleClassChangeError")

}

stack := frame.OperandStack()

slots := class.StaticVars()

// 3. 从Field的静态变量列表中获取值,push到操作数栈

switch field.Descriptor()[0] {

case 'Z', 'B', 'C', 'S', 'I':

stack.PushInt(slots.GetInt(field.SlotId()))

case 'F':

stack.PushFloat(slots.GetFloat(field.SlotId()))

case 'J':

stack.PushLong(slots.GetLong(field.SlotId()))

case 'D':

stack.PushDouble(slots.GetDouble(field.SlotId()))

case 'L', '[': // 对象或数组

stack.PushRef(slots.GetRef(field.SlotId()))

}

}

getfield

func (self *GET_FIELD) Execute(frame *rtda.Frame) {

cp := frame.Method().Class().ConstantPool()

// 1. 获取字段符号引用

fieldRef := cp.GetConstant(self.Index).(*heap.FieldRef)

// 2. 将字段符号引用解析为Field

field := fieldRef.ResolvedField()

if field.IsStatic() {

panic("java.lang.IncompatibleClassChangeError")

}

stack := frame.OperandStack()

// 3. 获取对象引用

ref := stack.PopRef()

if ref == nil {

panic("java.lang.NullPointerException")

}

slots := ref.Fields()

// 4. 从对象引用的实例变量列表中获取值,push到操作数栈

switch field.Descriptor()[0] {

case 'Z', 'B', 'C', 'S', 'I':

stack.PushInt(slots.GetInt(field.SlotId()))

case 'F':

stack.PushFloat(slots.GetFloat(field.SlotId()))

case 'J':

stack.PushLong(slots.GetLong(field.SlotId()))

case 'D':

stack.PushDouble(slots.GetDouble(field.SlotId()))

case 'L', '[': // 对象或数组

stack.PushRef(slots.GetRef(field.SlotId()))

}

}

checkcast

func (self *CHECK_CAST) Execute(frame *rtda.Frame) {

// 1. 从操作数栈获取对象引用ref

stack := frame.OperandStack()

ref := stack.PopRef()

stack.PushRef(ref)

// (Integer)null -> null引用可以转换为任何类型

if ref == nil {

return

}

cp := frame.Method().Class().ConstantPool() // 2. 获取当前栈帧所在类的常量池

classRef := cp.GetConstant(self.Index).(*heap.ClassRef) // 3. 获取类符号引用

class := classRef.ResolvedClass() // 4. 根据类符号引用创建类

if !ref.IsInstanceOf(class) { // 5. 判断 ref instanceof class

panic("java.lang.ClassCastException") // 6. 如果不是,抛异常

}

}

instanceof

func (self *INSTANCE_OF) Execute(frame *rtda.Frame) {

// 1. 从操作数栈获取对象引用ref

stack := frame.OperandStack()

ref := stack.PopRef()

// null instanceof Xxx -> false

if ref == nil {

stack.PushInt(0)

return

}

cp := frame.Method().Class().ConstantPool() // 2. 获取当前栈帧所在类的常量池

classRef := cp.GetConstant(self.Index).(*heap.ClassRef) // 3. 获取类符号引用

class := classRef.ResolvedClass() // 4. 根据类符号引用创建类

if ref.IsInstanceOf(class) { // 5. 判断 ref instanceof class

stack.PushInt(1) // 6. 将结果压入栈

} else {

stack.PushInt(0)

}

}

idc指令

func (self *LDC) Execute(frame *rtda.Frame) {

_ldc(frame, self.Index)

}

func (self *LDC_W) Execute(frame *rtda.Frame) {

_ldc(frame, self.Index)

}

func (self *LDC2_W) Execute(frame *rtda.Frame) {

// 1. 从运行时常量池获取常量c

stack := frame.OperandStack()

cp := frame.Method().Class().ConstantPool()

c := cp.GetConstant(self.Index)

// 2. 将常量c压入操作数栈

switch c.(type) {

case int64:

stack.PushLong(c.(int64))

case float64:

stack.PushDouble(c.(float64))

default:

panic("java.lang.ClassFormatError")

}

}

func _ldc(frame *rtda.Frame, index uint) {

// 1. 从运行时常量池获取常量c

stack := frame.OperandStack()

cp := frame.Method().Class().ConstantPool()

c := cp.GetConstant(index)

// 2. 将常量c压入操作数栈

switch c.(type) {

case int32:

stack.PushInt(c.(int32))

case float32:

stack.PushFloat(c.(float32))

//case string:

//case *heap.ClassRef:

default:

panic("todo:ldc!")

}

}

编写测试类

//测试classloader

func parseClassLoader(cmd *Cmd) {

cp := classpath.Parse(cmd.XjreOption, cmd.cpOption)

//获得classLoader

classLoader := heap.NewClassLoader(cp)

//获得加载类名字

className := strings.Replace(cmd.class, ".", "/", -1)

mainClass := classLoader.LoadClass(className)

//获得main方法

mainMethod := mainClass.GetMainMethod()

if mainMethod != nil {

interpret(mainMethod)

}else{

fmt.Printf("Main method not found in class %s\n",cmd.class)

}

}

shell脚本

go run main -test "classloader" -cp test/lib/example.jar jvmgo.book.ch06.MyObject #测试classloader

实战项目地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值