Java中的角色转换
我正在学习Java。我发现表达式通常必须转换为某种类型才能正确执行。例如,在算术计算期间,字节被提升为整数,因此以下表达式将抛出错误:Java中的角色转换,java,Java,我正在学习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 现在,我知道给字符变量赋值
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
现在,我知道给字符变量赋值一个整数是正确的:chara;a=88代码>可以。但是,如果我这样做:
char c2 = 'b', c3 = 'c';
c2 = c2 + c3; //throws error
c2 = (char)(c2 + c3); //works fine
为什么它在未浇铸时抛出错误?毕竟,右边仍然是一个整数,因此将整数赋给字符变量应该可以。在c2+c3
中,两个操作数都隐式加宽为int
,因此加法的结果也是int
:
对操作数执行二进制数字提升(§5.6.2)
:
当运算符将二进制数字提升应用于一对操作数(每个操作数必须表示可转换为数字类型的值)时,以下规则依次适用:
加宽原语转换(§5.1.2)用于转换以下规则指定的一个或两个操作数:
- 如果其中一个操作数的类型为double,则另一个操作数将转换为double
- 否则,如果其中一个操作数的类型为float,则另一个操作数将转换为float
- 否则,如果其中一个操作数的类型为long,则另一个操作数将转换为long
- 否则,两个操作数都转换为int类型。
因此,您将得到一个int
。将其分配给char
变量需要显式强制转换
你说:
由于整数值可以指定给字符变量
只有常量整数表达式才能分配给char
变量,而无需强制转换
:
此外,如果表达式是byte、short、char或int类型的常量表达式(§15.28):
- 如果变量的类型是byte、short或char,并且常量表达式的值可以在变量的类型中表示,则可以使用窄化原语转换
这种自动缩小转换在这里不适用。您需要一个显式强制转换。将int赋值给char并不一定很好。字符仅为16位,整数为32位,因此可能存在溢出
一般来说,如果赋值不会导致溢出,Java只允许在不强制转换的情况下赋值原语值。将int 88赋值给char有效,因为编译器可以确定值
编译器无法处理c2=c2+c3的情况。必须在运行时评估值c2+c3。因此,编译器无法确定必须分配的实际字符值
char c2 = 'b', c3 = 'c';
c2 = c2 + c3; //throws error
c2 = (char)(c2 + c3); //works fine
当您执行c2+c3
添加这些字符的ASCII值,返回int
结果。
将int
结果分配给char
时,会出现错误。char为2字节,int为4字节。当你写字符c=1时;这并不意味着1是int,它只是javac的一个常量,javac知道1适合于char。但c2=c2+c3;是算术运算,javac将其解释为(int)c2+(int)c3
,并生成int结果。int不适合char,因此javac警告您可能会丢失精度。查看线程:
原因似乎是“c2=c2+c3;”不能由编译器检查(它在运行时执行),而“char a;a=88;”则直接由编译器执行。进一步澄清的示例:
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);
因此,通过强制转换,我们实际上得到了一个错误的数学结果。对于java中每个基本类型可以保存的值有一定的限制。分配算术运算的结果可能会在运行时产生不可预测的结果,JVM不确定char是否可以保存,因此编译错误。88
是一个字节,不仅仅是一个整体是的,这就是我说的。右侧的字符提升为整数,从而将整数结果分配给左侧的变量。既然整数值可以分配给一个字符变量,为什么它会抛出一个错误?+1表示常量-我找不到引用;-)@库皮德沃格尔:那不太正确。只有常量整数表达式会自动缩小范围,这里我们不看一个。我已经扩展了答案。常量表达式的确切含义是什么?@Cupidvogel,如中定义的描述所述。基本上是:一个文本、一个final
变量或文本和final变量的组合。这里为什么会有溢出?很简单:取两个可能的最高字符值并添加它们。太多了<代码>('\uFFFF'+'\uFFFF')>Character.MAX_VALUE
这有点像快捷方式<代码>整数i=1;char c=i虽然没有溢出,但code>不会编译。嗯,因为它不是一个常量赋值,正如下面NPE所解释的那样?@Cupidvogel是的。例如final int i=1;char c=i
会编译,因为i
现在是一个常数代码>它不会抛出错误,为什么在这里呢?char c=99;99隐式转换为char。因为在编译时99的数据类型是已知的,但在编译时字符算术返回类型结果是未知的。为什么会这样?赋值之间的区别是什么?这里解释一下:它就是这样工作的:如果编译器可以动态地将一个数值转换为字节或字符,它就会这样做。如果在运行时执行分配,它将遵循其他转换路径。把它作为一个方便的编译器实用程序,或者作为语言中的一个不连贯性(以您最喜欢的为准;-)char是2字节,int是4字节。当你写字符c=1时;这并不意味着1就是一个