在Java中,允许以下内容:
char c = 'A' + 1;
这里,c将保持值'B'。在上面,首先评估表达式。因此'A'被转换为65,整个表达式的计算结果为66,然后66将转换为'B',因为我们将值存储在char中。
但是,以下内容会产生编译时错误:
char c = 'A';
c = c + 1;
Java如何以不同方式查看表达式的解释是什么?顺便说一下,以下工作也可以正常工作:
char c = 'A';
c++;
答案 0 :(得分:38)
第一个例子(编译)是特殊的,因为加法的两个操作数都是文字。
开头的一些定义:
将int
转换为char
称为narrowing primitive conversion,因为char
的类型小于int
。
'A' + 1
是constant expression。常量表达式(基本上)是一个表达式,其结果始终相同并且可以在编译时确定。特别是,'A' + 1
是一个常量表达式,因为+
的操作数都是文字。
此外,如果表达式[在右侧]是
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;
'A' + 99999
(100064
或0x186E0
)的值太大,无法容纳char
,因为char
is an unsigned 16-bit integer。
As for the postfix ++
operator:
后缀增量表达式的类型是变量的类型。
...
在添加之前,对值
1
和变量的值执行二进制数字提升*。 如果需要,总和会因缩小的原始转换而变窄,并且/或者在存储变量之前将其转换为变量的类型。
(* Binary numeric promotion获取byte
等运算符的short
,char
和+
个操作数,并将它们转换为int
或其他更大的类型。Java doesn't do arithmetic on integral types smaller than int
.)
换句话说,陈述c++;
大致相当于:
c = (char)(c + 1);
(不同之处在于表达式c++
的结果,如果我们将其分配给某些内容,则是之前c
的值增量。)
其他增量和减量的规格非常相似。
Compound assignment operators such as +=
automatically perform narrowing conversion as well,因此也允许c += 1
(甚至c += 3.14
)等表达式。
答案 1 :(得分:4)
char到int转换称为扩展转换。在扩大转换时,值不会丢失有关数值整体大小的信息,其中int转换为char转换称为缩小转换。随着转换范围的缩小,您可能会丢失有关数值整体幅度的信息,也可能会失去精确度。
有关原始转化的更多信息,请参阅this文档。
答案 2 :(得分:3)
这是因为编译器可以检查它('A' + 1)
是否在char的范围内,而它(通常)不能检查c + <an integer>
是否在边界内。
答案 3 :(得分:0)
因为整数或小于int的文字为byte,short和char为 int 。以这种方式理解以下内容。
代码:
byte a = 10;//compile fine
byte b= 11;//compile fine
byte c = a+b;//compiler error[says that result of **a+b** is **int**]
对于任何数学运算都会发生同样的情况,例如'Divide','multiply'和其他算术运算。所以转换结果以获得所需数据类型的文字
byte c = (byte)(a+b);
所以当你执行
c= c+1;//compiler error
它的结果是c + 1是int而不是char。所以编译器给出了相同的编译时错误。 所以你需要提供一个原始强制转换来将文字更改为char数据类型。 希望这个例子提供一些理解..