Java - char, int conversions

在 Java 中,允许执行以下操作:

char c = 'A' + 1;

在这里,c将保存值“B”。上面,首先计算表达式。因此,“A”转换为65,整个表达式的计算结果为66,然后将66转换为“B”,因为我们将值存储在char中。

但是,下面给出了编译时错误:

char c = 'A';
c = c + 1;

对于Java如何以不同的方式看待表达式,有什么解释?顺便说一句,以下内容也可以正常工作:

char c = 'A';
c++;

答案 1

第一个示例(编译)是特殊的,因为加法的两个操作数都是文字。

首先要参考几个定义:

  • 将转换为称为窄基元转换,因为 是比 小的类型。intcharcharint

  • 'A' + 1是一个常量表达式。常量表达式(基本上)是一个表达式,其结果始终相同,并且可以在编译时确定。特别是,是一个常量表达式,因为 的操作数都是文本。'A' + 1+

字节整型和字符的赋值期间,如果赋值的右侧是常量表达式,允许进行窄化转换

此外,如果表达式 [在右侧] 是类型 、 、 或 的常量表达式:byteshortcharint

  • 如果变量的类型为 、 或 ,并且常量表达式的值可以用变量的类型表示,则可以使用窄基元转换。byteshortchar

c + 1不是常量表达式,因为它是非变量,因此赋值会发生编译时错误。通过查看代码,我们可以确定结果始终相同,但在这种情况下不允许编译器这样做。cfinal

我们可以做的一件有趣的事情是:

final char a = 'a';
char b = a + 1;

在这种情况下一个常量表达式,因为它是一个用常量表达式初始化的变量。a + 1afinal

警告“如果[...]值 [...] 在变量的类型中是可表示的“表示以下内容不会编译:

char c = 'A' + 99999;

的值 (是 、 或 ) 太大而无法放入 ,因为 char 是无符号的 16 位整数'A' + 999991000640x186E0char


至于后缀 ++ 运算符

后缀增量表达式的类型是变量的类型。

...

在加法之前,对变量的值和值执行二进制数值提升*。如有必要,总和通过缩小基元转换和/或在存储变量之前进行装箱转换到变量的类型。1

(* 二进制数值提升采用 和 运算符的操作数,例如 和 将它们转换为 或其他更大的类型。Java 不对小于 int 的整数类型进行算术运算。byteshortchar+int)

换句话说,该语句主要等效于:c++;

c = (char)(c + 1);

(不同之处在于,如果我们将其分配给某个内容,则表达式的结果就是增量之前的值。c++c

其他增量和递减具有非常相似的规格。

复合赋值运算符(如 +=)也会自动执行窄转换,因此也允许使用(甚至)等表达式。c += 1c += 3.14


答案 2

字符到整数转换称为加宽转换。在加宽转换中,值不会丢失有关数值总体大小的信息,其中 int 到 char 的转换称为缩小转换。通过缩小转换范围,您可能会丢失有关数值总体大小的信息,也可能丢失精度。

有关基元转换的详细信息,请参阅文档。