[英]What does the "+=" operator do in Java?
您能帮我理解以下代码的含义吗:
x += 0.1;
编程的“常识”是x += y
是x = x + y
的等效简写符号。 只要x
和y
的类型相同(例如,两者都是int
s),您就可以认为这两个语句是等价的。
但是,在 Java 中, x += y
通常与x = x + y
。
如果x
和y
的类型不同,则这两个语句的行为因语言规则而异。 例如,让我们有x == 0
(int) 和y == 1.1
(double):
int x = 0;
x += 1.1; // just fine; hidden cast, x == 1 after assignment
x = x + 1.1; // won't compile! 'cannot convert from double to int'
+=
执行隐式转换,而对于+
您需要显式转换第二个操作数,否则会出现编译器错误。
引自 Joshua Bloch 的Java Puzzlers :
(...) 复合赋值表达式会自动将它们执行的计算结果转换为左侧变量的类型。 如果结果的类型与变量的类型相同,则强制转换无效。 然而,如果结果的类型比变量的类型更宽,复合赋值运算符将执行静默缩小原语转换 [ JLS 5.1.3 ]。
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 = x | y
等等 ...
它是赋值运算符之一。 它取x
的值,加上 0.1,然后将 (x + 0.1) 的结果存储回x
。
所以:
double x = 1.3;
x += 0.1; // sets 'x' to 1.4
它在功能上与以下内容相同,但比以下内容短:
double x = 1.3;
x = x + 0.1;
注意:在进行浮点数学运算时,事情并不总是像您认为的那样工作。
devtop += Math.pow(x[i] - mean, 2);
将Math.pow(x[i] - mean, 2)
运算的结果添加到devtop
变量中。
一个更简单的例子:
int devtop = 2;
devtop += 3; // devtop now equals 5
在 java 中,像 2 或 -2(没有小数部分)这样的数字的默认类型是 int,与 c# 不同,它不是一个对象,我们不能像在 c# 中那样做 2.tostring 之类的事情,以及像 2.5(带有小数部分)是双倍的; 所以如果你写:
short s = 2;
s = s + 4;
如果您执行以下操作,您将收到一个编译错误,即 int 也无法转换为 short:
float f = 4.6;
f = f + 4.3;
在两行将 double '4.6' 设置为 float 变量时,您会遇到两个编译错误,第一行的错误是合乎逻辑的,因为 float 和 double 使用不同的存储数字系统,使用一个而不是另一个会导致数据丢失; 提到的两个示例可以这样更改:
s += 4
f += 4.3
它们都在代码背后隐式转换并且没有编译错误; 值得考虑的另一点是“字节”数据类型范围内的数字在 java 中缓存,因此数字 -128 到 127 在 java 中属于字节类型,因此此代码没有任何编译错误:
byte b = 127
但这确实有一个错误:
byte b = 128
因为 128 是 java 中的 int; 关于长数字,我们建议在数字后使用 L 来解决整数溢出问题,如下所示:
long l = 2134324235234235L
在 java 中,我们没有像 c++ 那样的运算符重载,但是 += 仅针对 String 而不是针对 StringBuilder 或 StringBuffer 重载,我们可以使用它代替 String 'concat' 方法,但是我们知道 String 是不可变的,这将创建另一个对象并且不会像以前一样更改相同的对象:
String str = "Hello";
str += "World";
没关系;
devtop += Math.pow(x[i] - mean, 2);
添加Math.pow(x[i] - mean, 2)
到devtop
。
它通过+=
之后的值增加变量的值。 例如:
float x = 0;
x += 0.1;
//x is now 0.1
x += 0.1;
//x is now 0.2
它只是一个较短的版本:
x = x+0.1;
每当您想了解 Java 运算符的工作原理时,都可以查看字节码。 在这里编译:
int x = 0;
x += 0.1;
字节码将可以通过 jdk 命令javap -c [*.class]
:(您可以参考Java 字节码指令列表了解更多关于字节码的解释)
0: iconst_0 // load the int value 0 onto the stack
1: istore_1 // store int value into variable 1 (x)
2: iload_1 // load an int value from local variable 1 (x)
3: i2d // convert an int into a double (cast x to double)
4: ldc2_w #2 // double 0.1d -> push a constant value (0.1) from a constant pool onto the stack
7: dadd // add two doubles (pops two doubles from stack, adds them, and pushes the answer onto stack)
8: d2i // convert a double to an int (pops a value from stack, casts it to int and pushes it onto stack)
9: istore_1 // store int value into variable 1 (x)
现在很明显,java 编译器将x
提升为双倍,然后将其添加0.1
。
最后它将答案转换为integer
。
当你写作时,我发现了一个有趣的事实:
byte b = 10;
b += 0.1;
编译器将b
转换为 double ,将其加上0.1
,将double
的结果转换为integer
,最后将其转换为byte
,这是因为没有直接将double
为byte
指令。
如果您有疑问,可以检查字节码:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.