有人可以向我解释为什么以下代码在Java中编译好吗?
char c = 'a' + 10;
为什么这不等于以下,不编译?
int i = 10;
char c = 'a' + i;
Java语言规范(第3.10.1节)规定“如果整数文字的后缀为ASCII字母L或l(ell),则整数文字的类型为long
;否则为int
类型(§4.2.1)。“第4.2.2节引用“数值运算符,其结果为int
或long
类型的值。”因此,根据我的理解,添加的结果应为int
,无法将其分配给char
变量c
。
但是,它编译得很好(至少在Sun JDK 1.6.0版本17和Eclipse Helios中)。
或许是一个人为的例子,但是它被用在我一直在教的Java入门课程中,现在我发现我并不真正理解它为什么会起作用。
答案 0 :(得分:15)
这是因为编译器可以检查它('a' + 10
)是否在char的范围内,而它(通常)不能检查'a' + <an integer>
是否在边界内。
答案 1 :(得分:10)
'a' + 10
是编译时常量表达式,其值为'k'
,可以初始化类型为char
的变量。这与能够在[-128,127]中为文件整数分配byte
变量相同。 [128,255]范围内的byte
可能更烦人。
答案 2 :(得分:4)
char实际上是一个无符号的16位整数,范围为0-65535。因此,您可以将该范围内的任何整数字面值分配给char,例如“char c = 96”,这会导致“c”保持字符“a”。您可以使用System.out.println(c)打印出结果。
对于“char c ='a'+ 10”右侧的常量表达式,由于Java数字提升规则,“a”首先被提升为int,整数值为96.在图10中,我们得到一个文字整数106,可以将其分配给char。
“char c ='a'+ i”的右侧不是常量表达式,表达式结果赋值规则需要从int到char的显式强制转换,即“char c =(char)( 'a'+ i)“。
答案 3 :(得分:1)
常量是不同的类型(我知道规范说10
应该是一个int,但编译器不会那样看。)
在char c = 'a' + 10
中,10实际上被认为是char类型的常量变量(因此它可以添加到a中)。因此char c = char + char
有效。
在int i = 10;
char c = 'a' + i;
中你正在为一个整数添加一个字符(一个整数可以比一个字符大得多,所以它选择更大的数据类型[int
]作为结果aka:{{ 1}})。所以加法的结果是一个整数,它不能适合'a' + i = int + int
。
如果你明确地将char c
作为一个字符(例如:i
),它可以起作用,或者如果你做了相反的事情(例如:char c = 'a' + (char)i;
),它就可以了。
答案 4 :(得分:0)
根据 2020 中的 Java规范,用于扩大和缩小表达式中整数值的转换:
“在数字算术上下文中 ...提升的类型为
int
, 以及所有非int
类型的表达式都会扩大 原始转换到int
“
在分配上下文中:
” ......如果表达式是
byte
,short
类型的恒定表达式,char
或int
:•如果缩小原始转换, 变量的类型为
byte
,short
或char
,并且变量的值 常量表达式可以表示变量的类型。“
因此,在char c = 'a' + 10;
中,左常数为char
,右常数为int
,适合char
。当有一个赋值且int
可以容纳10个char
时,int
将转换为char
。加法的总结果为char
。
并且在char c = 'a' + i;
(其中int i = 10;
)中,i
不是常数,因此,尽管进行了分配,但char 'a'
仍被提升为int
,总体结果为int
。因此,没有明确的类型转换,分配是错误的。
请注意,以下原始答案是错误的(它引用了数字选择上下文中的处理方式,例如switch
语句中的内容)
根据 Java规范,用于扩大和缩小表达式中的转换:
如果任何表达式的类型为
int
,而不是常量表达式, 那么提升的类型为int
,以及其他非 类型int
进行 加宽基本转换到int
。...
如果任何表达式的类型为
char
,而其他所有表达式均为 类型为'char'或类型为'int'的常量表达式 可以在“ char”类型中表示的值,然后是提升的类型 是char
,并且int
表达式经过 narrowing 原语 转换到char
。
因此,在char c = 'a' + 10;
中,左边的表达式是char
,右边的常量表达式是int
,适合char
。因此,常数被转换为char
。总体结果是char
。
,在 char c = 'a' + i;
(其中int i = 10;
)中,正确的表达式不是常量,因此char 'a'
被提升为int
,而总体结果为int
。