第一个例子
让我们分析一下你做了什么。第一个例子是
((long) Math.pow(2, 31)) - 1;
这意味着您首先计算 Math.pow(2, 31) 从而产生
2.147_483_648 E9
然后你投到long。注意long 有足够的地方存放这个值,所以它表示为
2_147_483_648
然后你减去1得到
2_147_483_647
第二个例子
现在让我们看看第二个例子做了什么。你写的
(int) Math.pow(2, 31) - 1
这被解释为
((int) Math.pow(2, 31)) - 1
所以和以前一样,但转换为int 而不是long。现在请注意,int 确实 没有足够的位置 存放该值。最大可以表示的int是
2_147_483_647 // MAX_INTEGER
因此您也将在此处获得该值。之后你减去1 并得到
2_147_483_646
更正
我想你是这么想的
(int) Math.pow(2, 31) - 1
评估为
(int) (Math.pow(2, 31) - 1)
但事实并非如此。如果你明确表示你确实会得到 p>
2_147_483_647
正如预期的那样。
运算符优先级
您可以在 Java 语言规范 中阅读相关内容,请参阅 JLS§15.15 Unary Operators。强制转换优先于运算符,如减法。
这是因为 casting 是 unary operator 而减法是 binary。一元优先于二元。因此official documentation 给出了下表作为概述:
+----------------------------------------------------------------+
| Operators | Precedence (top is high, bottom low) |
|-----------------------|----------------------------------------|
| postfix | expr++ expr-- |
| unary | ++expr --expr +expr -expr ~ ! |
| multiplicative | * / % |
| additive | + - |
| shift | << >> >>> |
| relational | < > <= >= instanceof |
| equality | == != |
| bitwise AND | & |
| bitwise exclusive OR | ^ |
| bitwise inclusive OR | | |
| logical AND | && |
| logical OR | || |
| ternary | ? : |
| assignment | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
+----------------------------------------------------------------+
铸造当然是一元类别的一部分。