我有一个代码片段:
class AutoTypeCast{
public static void main(String...args){
int x=10;
byte b=20;//no compilation error
byte c=x;//compilation error
}
}
为什么20
被自动键入到byte
,而x
没有?
因为x
是int
,并且具有与byte
更宽的范围。这就是为什么如果将数据分配给byte
,可能会出现数据丢失的原因。
CCD_ 8是一个常数,而编译时假定在CCD_。
因为编译器在编译时无法计算出X的值。所以它假设X可以包含大于字节范围的值。如果您将变量X设为最终变量,那么它不会给您带来编译时错误。
final int x=10;
byte b=20;//no compilation error
byte c=x;//no compilation error
20总是可以用字节表示,而根据编译器的说法,x可以是任何整数,可能太大而无法用字节表示。
20
在-128..127
范围内,因此其值适合byte
。
在这种情况下,x
被初始化为10,因此在从32位int
到8位byte
的转换中不会出现数据丢失。但通常,当从int
转换为byte
时,可能会出现数据丢失,因此Java语言的规则禁止在没有强制转换的情况下将int
值分配给byte
。这个规则的设计目的是让编写有缺陷的代码变得更加困难。通过插入(byte)
强制转换,您实际上是在告诉编译器:"是的,我已经考虑过数据丢失的可能性,这在这里不是问题(或者,这实际上是我想要的)。"
当编译器查看行时
byte b=20;
它知道它在b=之后寻找一个字节。当它找到一个常量数值时,它在编译时就知道它肯定会在字节的范围内,所以它会自动强制转换它。
当is看到线路时
byte c=x;
它再次在c=之后寻找一个字节,但没有找到一个数字常量,而是找到了一个已经定义了类型的变量,并且在编译时无法确定它是否在字节的范围内,因此会出现错误。
X定义为整数,在缩小范围时可能会出现数据丢失,这就是编译器错误的原因。请参阅jvm规范中的转换&促销
向上强制转换是自动的,其中向下强制转换或缩小(byte c=x;
)应该是显式的,因为它可能会导致精度损失,程序员应该明确知道这一点。要更正它,您需要放置一个显式转换byte c=(byte)x;