yeshaoting 2011-04-20 17:02
浏览 271
已采纳

【字节码】如何理解构造函数中return指令?

经反编译后的构造函数,其字节码最后一条指令return如何理解?
构造函数没有数值返回类型,也非void返回类型,为何会有一条return指令存在?
这条指令在虚拟机中做了些什么工作?

 

public Test();
  Code:
   0: aload_0
   1: invokespecial #1; //Method java/lang/Object."<init>":()V
   4: return

  LineNumberTable: 
   line 10: 0

 


问题补充
devworks 写道
构造方法返回void

返回void为啥不显式地写在方法定义处.
问题补充
kerrysk 写道
return就是返回函数调用,没什么特殊含义。
这个是构造函数,在你在java内写new时,后面除了一条new指令外,还有个
invokespecial调用这个类的构造函数。
return指的是,pop构造函数frame,回到new指令所在的frame。


哦.
"pop构造函数frame,回到new指令所在的frame。"
确实是return指令的作用,没有特殊含义.

但为什么不显式写在定义处,虚拟机规范要特别采用隐式方式?
问题补充
mercyblitz 写道
yeshaoting 写道
devworks 写道
构造方法返回void

返回void为啥不显式地写在方法定义处.



构造器又不是方法,并且不需要return语句。


不需要return语句,为什么要加return指令...

问题补充
public Test()
{
System.out.println("public Test();");
}

public void Test()
{
System.out.println("public void Test();");
}

void能区分开构造函数与一般方法
问题补充
kerrysk 写道
return就是返回函数调用,没什么特殊含义。
这个是构造函数,在你在java内写new时,后面除了一条new指令外,还有个
invokespecial调用这个类的构造函数。
return指的是,pop构造函数frame,回到new指令所在的frame。


刚又理解了一下,解释得好.
加void与没加void,可能就是为着区分构造函数与一般方法吧.
问题补充
mercyblitz 写道
yeshaoting 写道
mercyblitz 写道
yeshaoting 写道
devworks 写道
构造方法返回void

返回void为啥不显式地写在方法定义处.



构造器又不是方法,并且不需要return语句。


不需要return语句,为什么要加return指令...


必要性和存在性不同,在实现构造器的时候,可以重用方法的部分语法检查!


嗯.对.
问题补充
kerrysk 写道
yeshaoting 写道

加void与没加void,可能就是为着区分构造函数与一般方法吧.

构造函数与一般方法在虚拟机内不是靠这个区分的。
构造函数与一般方法在虚拟机内的方法签名是不一样的,构造函数一般为<init>
一般方法为方法名。
虚拟机根据方法签名,在数据区加载相应的类,构造method结构体,里面有虚拟机指令,
解释器负责解释执行。每个方法调用,都在栈上push一个frame,在方法返回时pop,return是
用来告诉解释器,方法解释完毕,在栈上pop frame。

如果有返回值:
  sun虚拟机会返回到值栈的栈顶,供调用frame用。
  在dalvik下,是有类似return v0这样的指令,把v0放到全局ret变量,再在调用方法中用move_result指令放到调用栈的
寄存器中。
  也可以在设计invoke指令时,就将返回寄存器直接赋值到调用栈的寄存器中。

谢谢你的耐心讲解,最近在看虚拟机规范很多东西还没理解透彻.
  • 写回答

5条回答 默认 最新

  • kerry145296kkk 2011-04-20 17:02
    关注

    [quote="yeshaoting"]
    加void与没加void,可能就是为着区分构造函数与一般方法吧.[/quote]
    构造函数与一般方法在虚拟机内不是靠这个区分的。
    构造函数与一般方法在虚拟机内的方法签名是不一样的,构造函数一般为
    一般方法为方法名。
    虚拟机根据方法签名,在数据区加载相应的类,构造method结构体,里面有虚拟机指令,
    解释器负责解释执行。每个方法调用,都在栈上push一个frame,在方法返回时pop,return是
    用来告诉解释器,方法解释完毕,在栈上pop frame。

    如果有返回值:
    sun虚拟机会返回到值栈的栈顶,供调用frame用。
    在dalvik下,是有类似return v0这样的指令,把v0放到全局ret变量,再在调用方法中用move_result指令放到调用栈的
    寄存器中。
    也可以在设计invoke指令时,就将返回寄存器直接赋值到调用栈的寄存器中。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵