给定下面的代码,ixAdd 会做你所期望的,即在递增之前返回 ix 的值,但在离开函数之前递增类成员?
class myCounter {
private int _ix = 1;
public int ixAdd()
{
return _ix++;
}
}
当程序离开函数的堆栈框架(或Java中的任何内容)时,我不太确定后/前增量的通常规则是否也适用于返回语句。
关键部分是在计算表达式后立即发生后递增/递减。它不仅发生在返回发生之前 - 它发生在任何以后的表达式被评估之前。例如,假设您写道:
class myCounter {
private int _ix = 1;
public int ixAdd()
{
return _ix++ + giveMeZero();
}
public int giveMeZero()
{
System.out.println(_ix);
return 0;
}
}
这也会打印出递增的结果,因为递增发生在giveMeZero()
调用之前。
好吧,我们看一下字节码(javap -c <classname>
自己用来看):
Compiled from "PostIncTest.java"
class myCounter extends java.lang.Object{
myCounter();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_1
6: putfield #2; //Field _ix:I
9: return
public int ixAdd();
Code:
0: aload_0
1: dup
2: getfield #2; //Field _ix:I
5: dup_x1
6: iconst_1
7: iadd
8: putfield #2; //Field _ix:I
11: ireturn
}
如您所见,指令 6 和 7 在ixAdd()
返回之前处理增量。因此,正如我们所预料的那样,减量运算符在 return 语句中使用时确实有效果。但是请注意,dup
在这两个出现之前有一个指令;增加的值(当然)不会反映在返回值中。
是的,即使在退货声明中,通常的规则也适用于后期增量。基本上,它在低级别所做的是将返回值存储到寄存器中,然后递增类成员,然后从方法返回。
您可以在稍后对显示字节码的问题的回答中看到这一点。
是的,它确实。
但是不要那样做,在表达式中有副作用是不好的风格。
它确实返回递增之前的值,然后递增_ix。因此,第一次在 myCounter 实例上调用 ixAdd 方法时,它将返回 1,第二次将返回 2,以此类推。