a + = b和a = a + b之间的差异

时间:2012-01-07 21:45:21

标签: java operators

在Java中,我真的想知道使用a += b;a = a + b;之间是否存在差异。我应该主要使用哪一个?我知道第一个是快捷方式,但编译器是否会以不同的方式获得这两个指示?

9 个答案:

答案 0 :(得分:16)

请参阅Java language specification, 15.26.2 Compound assignment operators

引用相关部分:

  

形式E1 op = E2的复合赋值表达式是等价的   到E1 =(T)((E1)op(E2)),其中T是E1的类型,除了E1   仅评估一次。

short x = 3;
x += 4.6;
  

并导致x的值为7,因为它相当于:

short x = 3;
x = (short)(x + 4.6);

因此它不仅仅是语法糖,而是

int x = 1;
long a = 2l;
x+= a;

编译,其中

int x =1;
long a =2l;
x = x+a;

给出了编译错误,如here on StackOverflow quite recently

所述

答案 1 :(得分:3)

我知道大多数语言中的语法糖,包括c,c ++,C#,java,javascript ..

Cicada关于 c ++ 注意到的显着差异:

  

在数字类型(int和friends)上没有区别。       在用户定义的类上可能存在差异。       例如,值得注意的是来自DirectX的D3DXVECTOR3。       使用+会构造一个临时对象,而+ =则不会。       后者的速度提高了约30%。

答案 2 :(得分:3)

它确实取决于语言,但在c#中使用+ = b;效率稍高。

a仅评估一次。

在a = a + b中,a被评估两次。

http://msdn.microsoft.com/en-us/library/sa7629ew.aspx

答案 3 :(得分:2)

除了上述所有内容外,您还可以使用以下快捷方式:

运营商(+ =)

x+=y;

与:

相同
x=x+y;

运营商( - =)

x-=y;

与:

相同
x=x-y;

运营商(* =)

x*=y;

与:

相同
x=x*y;

运营商(/ =)

x/=y;

与:

相同
x=x/y;

运营商(%=)

x%=y;

与:

相同
x=x%y;

运营商(& =)

x&=y;

与:

相同
x=x&y;

运营商(| =)

x|=y;

与:

相同
x=x|y;

运营商(^ =)

x^=y; 

与:

相同
x=x^y;

运营商(>> =)

x>>=y;

相同
result=x>>y;

对运营商(<< =)和运营商(>>> =)的相同操作。

答案 4 :(得分:1)

在大多数情况下,它最终会成为同一件事。

在某些语言中+=是一个单独的运算符,可以重载以执行不同的操作。

例如在带有列表的Python中,行为是不同的(我学到了很多方法)

a = [1]
b = [2]
z = a
a = a + b
#z is not modified

a = [1]
b = [2]
z = a
a += b
# z is modified

答案 5 :(得分:1)

在大多数支持此注释的语言中,a = a + ba += b相同,但情况并非总是如此。

以下是Python中的一个示例(使用Numpy):

>>> import numpy as np
>>> a = np.array([1])
>>> b = np.array([2])
>>> c = a
>>> a = a + b
>>> print a
[3]
>>> print c
[1]

此处a = a + ba + b创建一个新数组,并将其存储到a中。 c使用与初始a相同的引用仍保留初始数组(值为1)。

>>> a = np.array([1])
>>> b = np.array([2])
>>> c = a
>>> a += b
>>> print a
[3]
>>> print c
[3]

此处a += b重新使用初始数组a。因此,由于ac都引用相同的数组,因此ac都会被修改。

答案 6 :(得分:1)

我更喜欢a += b而不是a = a + b。首先,它写得更少,其次更清楚的是发生了什么。在谈论C ++和类时,使用+ =可能更有效。看一下这个样本:

class C {
public:
    const C &operator =(const C &rhs) { printf("=\n"); x = rhs.x; return *this; }
    C operator +(const C &rhs) { printf("+\n"); C c; c.x = x + rhs.x; return c; }
    C &operator +=(const C &rhs) { printf("+=\n"); x += rhs.x; return *this; }

    int x;
};
C a, b;
a.x = 1;
b.x = 2;
a += b;     // same as a.operator+=(b)
a = a + b;  // same as a.operator=(a.operator+(b))

正如您在operator +=中所看到的,您拥有的临时对象更少,性能也更好。

答案 7 :(得分:0)

编译器 - (以及实现 - )定义编译器是否从上述源生成不同的代码,但有一点是肯定的:a + = b应该是a = a + b的更简单的简写符号。 (这就是为什么一般来说,理智的编译器会为两者生成相同的代码。)

答案 8 :(得分:0)

不,编译器不区分输出中的两个。唯一的区别在于解析和可能在词法分析中(取决于扩展)。您通常会使用快捷方式+=。这只是语法糖。