为什么以下代码转换为java字节码中的新+ dup op指令?

时间:2011-12-21 18:35:34

标签: java bytecode

假设我有一个Fraction课程:

class Fraction {
    ...

    /** Invert current fraction */
    public Fraction inverse() {
        return new Fraction(den,num);
    }

    ...
}

这就是上述方法的字节码结果是:

 0 new #1 <xyzTestes/system/fraction/Fraction>
 3 dup
 4 aload_0
 5 getfield #16 <xyzTestes/system/fraction/Fraction.den>
 8 aload_0
 9 getfield #14 <xyzTestes/system/fraction/Fraction.num>
12 invokespecial #27 <xyzTestes/system/fraction/Fraction.<init>>
15 areturn

我试图理解为什么第3位的指令首先放在那里。我要说我们只需要做以下工作就可以了:

 new #1 <xyzTestes/system/fraction/Fraction>
 aload_0
 getfield #16 <xyzTestes/system/fraction/Fraction.den>
 aload_0
 getfield #14 <xyzTestes/system/fraction/Fraction.num>
 invokespecial #27 <xyzTestes/system/fraction/Fraction.<init>>
 areturn

为什么不是这样?

2 个答案:

答案 0 :(得分:10)

当构造函数的字节码开始时,没有Fraction对象。 new指令从堆中分配Fraction对象(未初始化),并在堆栈上留下对它的引用。 dup指令可以使用一个引用来调用<init>,最后一个引用用于areturn

答案 1 :(得分:8)

您的字节码不正确。让我们一步一步:

new #1 <xyzTestes/system/fraction/Fraction>

堆栈Fraction实例(未初始化,只是指向内存的指针)

aload_0

堆叠Fraction(尚未初始化),this

getfield #16 <xyzTestes/system/fraction/Fraction.den>

堆叠Fraction(尚未初始化),this.den

aload_0
getfield #14 <xyzTestes/system/fraction/Fraction.num>

堆叠Fraction(尚未初始化),this.denthis.num

invokespecial #27 <xyzTestes/system/fraction/Fraction.<init>>

<强>堆栈

这很重要。所有invoke方法都要求堆栈包含this +所有参数。 this和参数都来自堆栈。调用后,只有一个返回值(如果有)放在堆栈上。 <init>的回复类型为void

这意味着您将致电:

areturn

在空堆栈上,吹灭JVM。