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 用三极管设计—个共射极放大电路
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示