6

我正在学习Java。我发现表达式通常必须转换为某种类型才能正确执行。例如,在算术评估期间,字节被提升为整数,因此以下表达式将引发错误:

byte b = 10;
int i;
i = b*b;  //ok, assigning an integer evaluation to an integer variable
b = b*b;  // throws error, coz assigning integer evaluation to byte variable

现在,我知道将整数分配给字符变量是可以的:char a; a = 88;没问题。但是,如果我这样做:

char c2 = 'b', c3 = 'c';
c2 = c2 + c3; //throws error
c2 = (char)(c2 + c3); //works fine

为什么它在不投射时会抛出错误?毕竟,右手边仍然是一个整数,所以将一个整数分配给一个字符变量应该可以正常工作。

4

8 回答 8

6

c2 + c3中,两个操作数都被隐式扩展为int,所以加法的结果也是一个int

JLS §15.18.2。数字类型的加法运算符(+ 和 -)

对操作数执行二进制数字提升(第 5.6.2 节)。

JLS §5.6.2。二进制数字提升

当运算符将二进制数值提升应用于一对操作数时,每个操作数都必须表示一个可转换为数值类型的值,以下规则按顺序适用:

加宽原语转换(第 5.1.2 节)适用于转换以下规则指定的一个或两个操作数:

  • 如果任一操作数是 double 类型,则另一个操作数将转换为 double。

  • 否则,如果任一操作数的类型为浮点型,则另一个将转换为浮点型。

  • 否则,如果任一操作数是 long 类型,则另一个将转换为 long。

  • 否则,两个操作数都转换为 int 类型。

因此,您最终得到一个int. 将其分配给char变量需要显式转换。

你说:

由于整数值可以分配给字符变量...

只有常量整数表达式可以在char没有强制转换的情况下分配给变量。

JLS §5.2。作业转换

此外,如果表达式是 byte、short、char 或 int 类型的常量表达式(第 15.28 节):

  • 如果变量的类型是 byte、short 或 char,并且常量表达式的值可以用变量的类型表示,则可以使用窄化原语转换。

此自动缩小转换不适用于此处。你需要一个明确的演员表。

于 2012-12-19T11:34:06.727 回答
3

将 int 分配给 char 不一定能正常工作。字符只有 16 位,整数是 32 位,因此可能存在溢出。

一般来说,如果分配不会发生溢出,Java 只允许在没有强制转换的情况下分配原始值。

于 2012-12-19T11:34:08.163 回答
1
char c2 = 'b', c3 = 'c';
c2 = c2 + c3; //throws error
c2 = (char)(c2 + c3); //works fine

当你在做c2+ c3

添加这些字符的 ASCII 值,返回int结果。当您将int结果分配给char 它时会出错。

于 2012-12-19T11:36:19.107 回答
0

将 int 88 分配给 char 有效,因为编译器可以确定该值。

编译器无法处理 c2 = c2 + c3 的情况。值 c2 + c3 必须在运行时计算。因此,编译器无法确定必须分配的实际 char 值。

于 2012-12-19T11:35:57.633 回答
0

char 是 2 个字节,int 是 4 个字节。当你写 char c = 1; 这并不意味着 1 是 int,它只是 javac 的一个常量,javac 知道 1 适合 char。但是 c2 = c2 + c3; 是算术运算,javac 会将其解释为(int)c2 + (int)c3,这会产生 int 结果。int 不适合 char 因此 javac 警告您可能会丢失精度。

于 2012-12-19T11:39:27.990 回答
0

看看线程:

Java中的整数算术与char和整数文字

原因似乎是“c2 = c2 + c3;” 编译器无法检查(它在运行时执行)而“char a; a = 88;” 由编译器直接完成。

于 2012-12-19T11:39:37.417 回答
0

java中每种基本类型可以容纳多少值有一定的限制。分配算术运算的结果会在运行时产生不可预测的结果,JVM不确定char是否可以容纳,因此编译错误。

于 2012-12-19T11:52:38.300 回答
0

进一步说明的示例:

char c1 = Character.MAX_VALUE;
char c2 = Character.MAX_VALUE;
char c3 = (char) (c1 + c2);
int  i3 = c1 + c2;

System.out.printf("After casting to char: %s, the int value: %s%n", (int) c3, i3);

因此,通过强制转换,我们实际上得到了错误的数学结果。

于 2012-12-19T11:45:07.130 回答