为什么以下代码转换为java字节码中的新+ dup op指令?
假设我有一个Fraction
类:
class Fraction { ... /** Invert current fraction */ public Fraction inverse() { return new Fraction(den,num); } ... }
这就是上述方法的字节码结果如下:
0 new #1 3 dup 4 aload_0 5 getfield #16 8 aload_0 9 getfield #14 12 invokespecial #27 <xyzTestes/system/fraction/Fraction.> 15 areturn
我试图理解为什么第3位的教学首先放在那里。 我要说我们只需要做以下工作就可以了:
new #1 aload_0 getfield #16 aload_0 getfield #14 invokespecial #27 <xyzTestes/system/fraction/Fraction.> areturn
为什么不是这样?
当构造函数的字节码开始时,没有Fraction对象。 new
指令从堆中分配一个Fraction
对象(未初始化),并在堆栈上留下对它的引用。 dup
指令是这样的,一个引用可用于调用
,第二个引用用于最后的结果。
你的字节码不正确。 让我们一步一步:
new #1
堆栈 : Fraction
实例(未初始化,仅指向内存的指针)
aload_0
Stack : Fraction
(仍然未初始化), this
getfield #16
Stack : Fraction
(仍然未初始化), this.den
aload_0 getfield #14
Stack : Fraction
(仍然未初始化), this.den
, this.num
invokespecial #27 >
堆栈 :
这很关键。 所有invoke
方法都要求堆栈包含this
+所有参数。 this
和参数都来自堆栈。 在调用之后,只有一个返回值(如果有)放在堆栈上。
具有void
返回类型。
这意味着您将致电:
areturn
在空堆栈上,吹灭JVM。
- 如何在Java中注释对类的弃用?
- 为什么JAXB生成的类具有受保护的成员?如何更改它?
- JPA无法解析列/ IntelliJ
- java.lang.ClassCastException:java.lang.Long无法在java 1.6中强制转换为java.lang.Integer
- SimpleStringProperty set()与setValue()
- 如何杀死Ant启动的失控Java进程?
- 如何将Hibernate NamingStrategy迁移到(隐式|物理)NamingStrategy? 文件在哪里?
- 无法解析主URL:’spark:http:// localhost:18080′
- Javagenerics:类型不匹配:无法从Integer转换为K.