在Java中,以下内容是允许的:
char c = 'A' + 1;
在这里,c将保存值'B'。首先,表达式将被评估。因此'A'被转换为65,整个表达式评估为66,然后由于我们将值存储在char中,66被转换为'B'。
然而,以下代码将产生编译时错误:
char c = 'A';
c = c + 1;
Java是如何解释表达式的差异的?顺便说一句,以下代码也可以正常工作:
char c = 'A';
c++;
在Java中,以下内容是允许的:
char c = 'A' + 1;
在这里,c将保存值'B'。首先,表达式将被评估。因此'A'被转换为65,整个表达式评估为66,然后由于我们将值存储在char中,66被转换为'B'。
然而,以下代码将产生编译时错误:
char c = 'A';
c = c + 1;
Java是如何解释表达式的差异的?顺便说一句,以下代码也可以正常工作:
char c = 'A';
c++;
第一个例子(可以编译)很特殊,因为加法的两个操作数都是字面量。
首先需要了解一些定义:
将int
转换为char
称为缩小原始类型转换,因为char
比int
更小。
'A' + 1
是一个常量表达式。 常量表达式是(基本上)其结果始终相同且可以在编译时确定的表达式。 特别地,'A' + 1
是一个常量表达式,因为+
的操作数都是字面量。
在赋值时,允许对byte
、short
和char
进行缩窄转换,如果赋值右侧为常量表达式:
此外,如果表达式[在赋值右侧]是
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
是一个无符号16位整数。
后缀递增表达式的类型是变量的类型。
...
在添加之前,对值
1
和变量的值执行二进制数值提升*。 如果需要,将通过缩小原始转换来缩小总和,并/或将其转换为变量的类型进行装箱转换,然后再存储。
(* 二进制数值提升将操作数(如+
)的byte
、short
和char
转换为int
或其他更大的类型。Java不对小于int
的整数类型进行算术运算。)
换句话说,语句c++;
大多等效于:
c = (char)(c + 1);
c++
, if we assigned it to something, is the value of c
before the increment.)+=
也会自动进行缩小转换, 因此像c += 1
(甚至c += 3.14
)这样的表达式也是允许的。char c = (char)('A' + 99999);
。 - Radiodef将字符转换为整数被称为扩展转换。在扩展转换中,值不会丢失关于数字值总大小的信息,而将整数转换为字符被称为缩小转换。使用缩小转换,您可能会失去有关数字值总大小的信息,并可能损失精度。
有关基本转换的更多信息,请参阅此文档。
编译器之所以可以检查('A' + 1)
是否在char类型的范围内,是因为它可以进行边界检查。而对于c + <an integer>
(其中c为变量),编译器通常无法进行边界检查。
这是因为整数或比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**]
对于任何数学运算,如“除法”、“乘法”和其他算术运算,都会发生同样的情况。因此,将结果转换为所需数据类型的字面量。
byte c = (byte)(a+b);
所以当你执行
c= c+1;//compiler error
c+1的结果是int类型而不是char类型。因此编译器会为此产生编译时错误。 所以您需要提供一个基本的强制转换来将文字转换为char数据类型。 希望这个例子能提供一些理解。。
char
是一个遗留类型,自 Java 2 以来基本上已经失效。作为一个 16 位值,char
在物理上无法表示大多数字符。相反,当处理单个字符时,请学习使用 代码点 整数。您将在各种类中找到与代码点相关的方法,包括String
、StringBuilder
、Character
等。 - Basil Bourque