`
yeshaoting
  • 浏览: 669781 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

    博客分类:
  • JVM
阅读更多

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

 

字节码代码   收藏代码
  1. public Test();  
  2.   Code:  
  3.    0: aload_0  
  4.    1: invokespecial #1; //Method java/lang/Object."<init>":()V  
  5.    4: return  
  6.   
  7.   LineNumberTable:   
  8.    line 100  

 


问题补充

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指令时,就将返回寄存器直接赋值到调用栈的寄存器中。 


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

 

分享到:
评论

相关推荐

    java面试宝典

    81、public class Something { public int addOne(final int x) { return ++x; }}这个比较明显。 19 83、class Something { int i; public void doSomething() { System.out.println("i = " + i); }} 有什么错呢? 19...

    千方百计笔试题大全

    81、public class Something { public int addOne(final int x) { return ++x; }}这个比较明显。 19 83、class Something { int i; public void doSomething() { System.out.println("i = " + i); }} 有什么错呢? 19...

    Java面试宝典2010版

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    语言程序设计课后习题答案

    编程显示你使用的计算机中的各种数据类型的字节数。 解: 源程序: #include &lt;iostream.h&gt; int main() { cout (int) ; cout (short) ; cout (long) ; cout (char) ; cout (float) ; cout (double) ; return 0; } ...

    最新Java面试宝典pdf版

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    Java面试笔试资料大全

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    JAVA面试宝典2010

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    Java面试宝典-经典

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    java面试题大全(2012版)

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    java面试宝典2012

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    Java面试宝典2012版

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    Java面试宝典2012新版

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    java 面试题 总结

    不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface)...

    超级有影响力霸气的Java面试题大全文档

    不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。  接口(interface...

    java面试题

    84.7. 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+...

    c#学习笔记.txt

    readonly声明一个字段,该字段只能赋值为该声明的一部分或者在同一类的构造函数中。 sealed指定类不能被继承。 static声明属于类型本身而不是属于特定对象的成员。 unsafe声明不安全的上下文。 virtual在派生类中...

    51单片机C语言编程基础及实例

    以单支共阴数码管为例,可将段极接到某端口 Pn,共阴极接 GND,则可编写出对应十六进制码的 七段码表字节数据如右图: 16 键码显示的程序 我们在 P1 端口接一支共阴数码管 SLED,在 P2、P3 端口接 16 个按键,分别...

    Java 面试宝典

    19、构造器 Constructor 是否可被 override? ................................................................ 15 20、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继 承具体类...

Global site tag (gtag.js) - Google Analytics