经反编译后的构造函数,其字节码最后一条指令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指令时,就将返回寄存器直接赋值到调用栈的寄存器中。
谢谢你的耐心讲解,最近在看虚拟机规范很多东西还没理解透彻.
分享到:
相关推荐
方法表包含方法的元数据,如方法名、返回类型、参数列表和字节码指令。 8. **属性表** 附加属性表提供额外信息,如`Code`属性包含了方法的实际字节码,`Exceptions`属性记录了可能抛出的异常,`Annotations`和`...
6. **方法调用与返回指令**:`invokevirtual`用于调用对象的虚方法,`invokespecial`用于构造函数调用和私有方法,`return`表示方法的结束。 7. **异常处理指令**:如`athrow`抛出异常,`catch`配合`try-catch`块...
Java虚拟机(JVM)是Java程序运行的核心,它的核心组件之一就是字节码指令集。字节码是一种低级的、平台无关的指令集,它由一系列单字节的操作码(Opcode)和可能的参数(Operands)组成,使得Java程序能在任何支持...
4. **类和接口操作指令**:如`aload_0`加载局部变量0(通常为this引用),`invokevirtual`调用实例方法,`invokespecial`调用构造函数或私有方法。 5. **异常处理指令**:`athrow`用于抛出一个异常,`catch`配合try...
这段代码表示一个简单的构造函数,调用了父类的构造函数并返回。 5. **使用Smali-2.5.2.jar** 这个jar文件可能是用于解析和编译Smali代码的工具集,包括反编译.dex到Smali,以及将Smali编译回.dex的工具。开发者...
静态解析发生在类加载时,针对静态方法、私有方法、final方法、构造函数和父类中的方法。动态解析则在运行时进行,比如接口方法调用和动态语言支持。 分派是JVM确定具体调用哪个方法的过程,分为静态分派(编译时...
JVM使得这一目标得以实现,因为它可以根据底层硬件平台的指令集和特性来执行字节码。 #### 2. JDK和JRE的区别是什么? - **Java运行时环境(JRE)**包含了执行Java程序所需的Java虚拟机和浏览器插件(用于执行Applet...
- 错误: `final`修饰的变量必须在声明时初始化,或在构造函数中初始化。 - 改正: 初始化`final`变量。 ```java class Something { final int i = 10; // 或者在构造函数中初始化 public void doSomething() { ...
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...
例如,ARM指令通常由4个字节组成,其中包含操作码和操作数。每个gadget都需要精心挑选,以确保它们能够无缝连接,形成完整的功能。 3. Gadgets的查找与利用 Gadgets是ROP的核心,它们是从程序的已加载库或可执行...
在构造函数中,我们指定串口名(如"COM1")和波特率(如9600),然后打开连接。`QueryStatus`方法发送查询指令并接收响应。 实际项目中,你还需要处理错误,例如串口未找到、连接失败、数据读取超时等。同时,响应...
- 类加载器将`.class`文件读入内存,并进行字节码验证、解析和初始化等步骤。 16. **封装具有的特性**:保护内部状态、提供对外接口、提高模块化和维护性。 17. **什么时候应用带参构造函数?** - 需要初始化...
4. **解析**:此时JVM将常量池中的符号引用替换为直接引用,使得后续的字节码指令可以直接操作这些引用。 5. **初始化**:最后,执行类的`<clinit>`方法,它是由编译器自动合成的,包含了静态变量的显式赋值语句和...
如果当前线程正在执行的是Java方法,那么程序计数器中记录的是正在执行的字节码文件的地址;如果是Native方法,程序计数器的值是未定义的。 - **特点**:每个线程都有一个私有的程序计数器,确保了多线程环境下每个...
1. **new对象底层字节码指令分析**:在Java字节码中,`new`指令用于创建一个对象,`dup`用于复制对象引用,`invokespecial`调用构造函数,`pop`用于弹出栈顶的引用,如果有多次`new`,则需要重复这些步骤。...
- JVM是Java程序运行的平台,它将Java字节码解释成特定硬件平台的机器指令。 - 字节码的好处包括跨平台能力和优化潜力,因为JVM可以进行动态优化。 4. **Java语言的结构**: - 源代码文件以`.java`结尾,编译后...
使用Java编译器(javac)将JavaBean源代码编译成字节码文件(.class)。例如: ``` javac User.java ``` 3. **在JSP中导入JavaBean** 在JSP文件中,可以通过`<jsp:useBean>`指令来实例化JavaBean。例如: ```...
Java源代码编译成字节码后,可以在任何支持JVM的平台上运行,JVM负责将字节码转换为对应平台的机器指令。 3. **String是否为基本类型**:String不是基本类型,而是引用类型,它继承自Object类,不可被继承。 4. **...
编程显示你使用的计算机中的各种数据类型的字节数。 解: 源程序: #include <iostream.h> int main() { cout (int) ; cout (short) ; cout (long) ; cout (char) ; cout (float) ; cout (double) ; return 0; } ...