Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.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,我知道增量前后(如++I,I++,--I,I--)用于速记,在增量之前或之后获取值。这也可以通过其他方法实现。但是,它们还有其他优势吗?那么,它们之间的区别是什么: x++ ++x x+=1 x=x+1 如所述: 在JIT有机会处理代码之后,不应该有任何其他优势。它们将被编译成相同的东西 但是,如果将4用作独立语句,则这是一个真正的语句。它们中的所有4个也可以用作表达式,在这种情况下,它们并不完全相同: a=x++是递增x之前的值 a=++x、a=x+=1和a=x=x+1都是递增x后的值

我知道增量前后(如
++I,I++,--I,I--
)用于速记,在增量之前或之后获取值。这也可以通过其他方法实现。但是,它们还有其他优势吗?

那么,它们之间的区别是什么:

  • x++
  • ++x
  • x+=1
  • x=x+1
如所述:

在JIT有机会处理代码之后,不应该有任何其他优势。它们将被编译成相同的东西

但是,如果将4用作独立语句,则这是一个真正的语句。它们中的所有4个也可以用作表达式,在这种情况下,它们并不完全相同:

  • a=x++
    是递增
    x
    之前的值
  • a=++x
    a=x+=1
    a=x=x+1
    都是递增
    x
    后的值
另外,
x=x+1
计算
x
两次,而其他3次只计算一次。对于没有区别的简单
x
,但是对于有区别的数组查找
a[k]
,尤其是当“k”可以更改时

例如:

// setup
int[] a = { 5, 15, 25 };
int k = 0;

// result of each if run right after setup
a[k++]++;            // k = 1, a = [6, 15, 25]
++a[k++];            // k = 1, a = [6, 15, 25]
a[k++] += 1;         // k = 1, a = [6, 15, 25]

a[++k]++;            // k = 1, a = [5, 16, 25]
a[k+=1]++;           // k = 1, a = [5, 16, 25]
a[k=k+1]++;          // k = 1, a = [5, 16, 25]

a[k++] = a[k++] + 1; // k = 2, a = [16, 15, 25]
最后一个是doozie。有关其工作原理的详细说明,请参见,但它从左到右计算:

k = 0;    a[k++] = a[k++] + 1;
k = 1;    a[0] = a[k++] + 1;
k = 2;    a[0] = a[1] + 1;
k = 2;    a[0] = 15 + 1;
k = 2;    a[0] = 16;
重述一下:

  • 如果作为语句运行,则没有区别,
    x
    没有副作用(非常常见)
  • 作为一个表达式,
    x++
    post增量计算为不同的值
  • x=x+1
    评估
    x
    两次,如果
    x
    有副作用(罕见),这很重要
除此之外,使用哪一个是一个选择的问题


字节码

对于那些使用Eclipse编译器对字节码感兴趣的人来说,如果“x”是一个简单变量,那么所有4条as语句都会编译为

iinc          1, 1
作为带有简单变量的表达式,例如
y=x++
,它们的编译方式不同:

// y = x++;
iload_2
iinc          2, 1
istore_1

// y = ++x;   y = x += 1;   y = x = x + 1;
iinc          2, 1
iload_2
istore_1
使用阵列:

// y = a[k]++;
aload_1
iload_2
dup2
iaload
dup_x2
iconst_1
iadd
iastore
istore_3

// y = ++a[k];   y = a[k] += 1;
aload_1
iload_2
dup2
iaload
iconst_1
iadd
dup_x2
iastore
istore_3

// y = a[k] = a[k] + 1;
aload_1
iload_2
aload_1
iload_2
iaload
iconst_1
iadd
dup_x2
iastore
istore_3

注意,您也可以对
i+=1
i-=1
执行相同的操作。不,JIT有机会处理代码后,不应该有任何其他优势。它们将被编译成相同的内容。@科学方法数组索引是增量前后
s[i++]=m[j++]的常用方法
这些值不相等,因为
i
j
的值不会更新。@Mick所说的科学方法是正确的。你写的和我写的完全不同。您的代码计算
i+1
,但不执行其他操作
i++
使用
i
的当前值(不是i+1),然后在以后的所有计算中增加
i
的值。为什么要多次计算
x
?你能从你的例子中打印出字节码吗?@Kayaman在
x=x+1
中,子表达式“x”被计算两次,因为语言是这样定义的。作为一个简单的变量,例如“x”是
i
,就像在
i=i+1
中一样,你永远不会注意到,但是如果“x”是
a[k++]
,它会产生巨大的差异,正如我的答案中明确所述。当然,对于更复杂的表达式,它是有意义的。我只是想知道这种双重计算是否会出现在字节码中。@Kayaman补充了一些例子,说明字节码在某些情况下是如何不同的。使用数组时,将显示双重求值。谢谢。所以
y=++x;y=x+=1;y=x=x+1
在字节码中是等价的,更复杂的表达式显然不是。