第一个示例(编译)是特殊的,因为加法的两个操作数都是文字。
首先要参考几个定义:
在字节
、短
整型和字符
的赋值期间,如果赋值的右侧是常量表达式,则允许进行窄化转换:
此外,如果表达式 [在右侧] 是类型 、 、 或 的常量表达式:byte
short
char
int
- 如果变量的类型为 、 或 ,并且常量表达式的值可以用变量的类型表示,则可以使用窄基元转换。
byte
short
char
c + 1
不是常量表达式,因为它是非变量,因此赋值会发生编译时错误。通过查看代码,我们可以确定结果始终相同,但在这种情况下不允许编译器这样做。c
final
我们可以做的一件有趣的事情是:
final char a = 'a';
char b = a + 1;
在这种情况下是一个常量表达式,因为它是一个用常量表达式初始化的变量。a + 1
a
final
警告“如果[...]值 [...] 在变量的类型中是可表示的“表示以下内容不会编译:
char c = 'A' + 99999;
的值 (是 、 或 ) 太大而无法放入 ,因为 char
是无符号的 16 位整数。'A' + 99999
100064
0x186E0
char
至于后缀 ++
运算符:
后缀增量表达式的类型是变量的类型。
...
在加法之前,对变量的值和值执行二进制数值提升*。如有必要,总和通过缩小基元转换和/或在存储变量之前进行装箱转换到变量的类型。1
(* 二进制数值提升采用 和 运算符的操作数,例如 和 将它们转换为 或其他更大的类型。Java 不对小于 int
的整数类型进行算术运算。byte
short
char
+
int
)
换句话说,该语句主要等效于:c++;
c = (char)(c + 1);
(不同之处在于,如果我们将其分配给某个内容,则表达式的结果就是增量之前的值。c++
c
其他增量和递减具有非常相似的规格。
复合赋值运算符(如 +=)
也会自动执行窄转换,因此也允许使用(甚至)等表达式。c += 1
c += 3.14