Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中,增量后运算符如何在返回语句中起作用?_Java_Operators - Fatal编程技术网

在Java中,增量后运算符如何在返回语句中起作用?

在Java中,增量后运算符如何在返回语句中起作用?,java,operators,Java,Operators,给定下面的代码,ixAdd会做您期望的事情吗。E在递增之前返回ix的值,但在离开函数之前递增类成员 class myCounter { private int _ix = 1; public int ixAdd() { return _ix++; } } 我不确定当程序离开函数的堆栈帧(或Java中的任何内容)时,增量后/增量前的常规规则是否也适用于返回语句。是的,即使在返回语句中,常规规则也适用于增量后。基本上,它将在低级别执行的操作是将返回

给定下面的代码,ixAdd会做您期望的事情吗。E在递增之前返回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
自己查看):

从“PostIncTest.java”编译而来
类myCounter扩展了java.lang.Object{
myCounter();
代码:
0:aload_0
1:invokespecial#1;//方法java/lang/Object。“:()V
4:aload_0
5:iconst_1
6:putfield#2;//字段_ix:I
9:返回
公共int ixAdd();
代码:
0:aload_0
1:dup
2:getfield#2;//字段_ix:I
5:dup_x1
6:iconst_1
7:iadd
8:putfield#2;//字段_ix:I
11:我轮到你了
}

如您所见,
ixAdd()
中的说明6和7处理返回之前的增量。因此,正如我们所期望的,减量运算符在return语句中使用时确实有效果。但是,请注意,在这两条指令出现之前有一条
dup
指令;递增的值(当然)不会反映在返回值中。

它会在递增之前返回值,然后再递增ix。因此,在myCounter实例上第一次调用方法ixAdd时,它将返回1,第二次将返回2,依此类推。

ehm。。你的意思是,像在我的编辑器中粘贴上面的代码并运行它?我不知道,对不起-p我去给自己拿杯咖啡…投票支持close。。。我以为作者可以马上关闭它?嘿,现在我知道为什么我没有尝试:得到乔恩·斯基特的答案。它实际上比这个问题更有用。@PT有趣的是,它本来很容易尝试:)谢谢你的回答,乔恩。正如PaulTomblin指出的那样,在我的编辑器中而不是在帖子中键入代码也可以解决这个问题。但是现在我从中得到的比我要求的更多。@Jon:对于从C到Java的人来说(这将是很多人),这是一件值得指出的事情。作为一个很长很长时间第一次使用C的Java用户,我不知道Java比C更清楚地定义了++的工作原理。我学会了避免“聪明”++使用C!它不仅发生在返回发生之前,而且如果返回语句是局部变量,它也不会返回递增的值。您的示例显示了一个全局变量。@ernesto:它没有任何区别:return语句返回表达式的值,该值将是预增量值。无论它使用局部变量还是字段,这都是一样的。该字段用于显示
giveMeZero
方法观察递增的值。这里的副作用是非常有意的,我看不出它有什么害处。
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

}