Java - char、int 转换
Posted
技术标签:
【中文标题】Java - char、int 转换【英文标题】:Java - char, int conversions 【发布时间】:2014-02-14 13:25:26 【问题描述】:在 Java 中,允许以下内容:
char c = 'A' + 1;
在这里,c 将保存值“B”。上面,首先计算表达式。所以“A”被转换为 65,整个表达式的计算结果为 66,然后 66 被转换为“B”,因为我们将值存储在一个字符中。
但是,以下给出了编译时错误:
char c = 'A';
c = c + 1;
Java 如何以不同方式看待表达式的解释是什么?顺便说一句,以下内容也可以正常工作:
char c = 'A';
c++;
【问题讨论】:
请查看以下问题,特别是 rgettman 的回答:***.com/questions/18648283/… 我不确定说 66 转换为 'B' 是否准确。字符基本上已经是数字了。 @Piovezan 尽管spec does describe char as a range of code points 和积分范围都很有趣。对于文字,字符文字 ('B') 始终是 char 类型,当然 66 始终是 int 类型。也许最准确的说法是它被转换为 '\u0042'(一个始终为 char 类型的数字代码)。 这是一个很好的问题,我以前没有看到这样的问题。真棒的问题。你接受的答案也很好,对你来说也很完善。 【参考方案1】:第一个例子(编译)是特殊的,因为加法的两个操作数都是文字。
一些定义开始:
将int
转换为char
称为narrowing primitive conversion,因为char
是比int
更小的类型。
'A' + 1
是constant expression。常量表达式(基本上)是结果始终相同并且可以在编译时确定的表达式。特别是,'A' + 1
是一个常量表达式,因为+
的操作数都是文字。
A narrowing conversion is allowed during the assignments of byte
, short
and char
, if the right-hand side of the assignment is a constant expression:
另外,如果[右边的]表达式是
如果变量的类型为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++
的result,如果我们把它赋值给某个东西,就是c
的值在增量之前。)
其他增量和减量具有非常相似的规范。
Compound assignment operators such as +=
automatically perform narrowing conversion as well,因此c += 1
(甚至c += 3.14
)等表达式也是允许的。
【讨论】:
我猜 Java 应用这个规则的原因是因为(正如 Brian 所说)Java 无法确定整数是否在范围内。 基本上是的。缩小转换意味着可能存在溢出,Java 希望这种可能性是明确的。你总是可以做类似char c = (char)('A' + 99999);
的事情。【参考方案2】:
char 到 int 的转换称为加宽转换。在扩大转换中,值不会丢失有关数值整体大小的信息,其中将 int 转换为 char 称为缩小转换。通过缩小转换,您可能会丢失有关数值整体大小的信息,也可能会丢失精度。
有关原始转换的更多信息,请参阅this 文档。
【讨论】:
【参考方案3】:这是因为编译器可以检查 ('A' + 1)
是否在 char 的范围内,而它不能(通常)检查 c + <an integer>
是否在范围内。
【讨论】:
【参考方案4】:这是因为整数或小于 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 数据类型。 希望这个例子能提供一些理解..
【讨论】:
以上是关于Java - char、int 转换的主要内容,如果未能解决你的问题,请参考以下文章
Java中三元运算符中的char转换,打印int值而不是char值
Java char int 转换/char[]char数组 字符串 转换 String.valueOf/Arrays.sort/int[]数组初始0/Integer[]数组初始null