我有一段代码:
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
,而{{1}}没有?
答案 0 :(得分:5)
因为x
是int
,并且范围更广,为byte
。这就是为什么可能会有数据丢失,您将其分配给byte
。
20
是一个常量,编译时间保证在byte
范围内。
答案 1 :(得分:3)
因为编译器无法在编译时计算出X的值。所以它假设X可以包含大于字节范围的值。如果将变量X作为final,则不会给出编译时错误。
final int x=10;
byte b=20;//no compilation error
byte c=x;//no compilation error
答案 2 :(得分:1)
20总是可以用一个字节表示,而x,根据编译器可以是任何整数,可能太大而不能用字节表示。
答案 3 :(得分:1)
20
位于-128..127
范围内,因此它的值适合byte
。
答案 4 :(得分:1)
在这种情况下,x
初始化为10,因此从32位int
到8位byte
的转换不会丢失数据。但一般情况下,从int
转换为byte
时,可能会丢失数据,因此Java语言的规则禁止在没有强制转换的情况下将int
值分配给byte
。此规则旨在使编写错误代码变得更加困难。通过插入(byte)
强制转换,您实际上是在告诉编译器:“是的,我已经考虑过数据丢失的可能性,这不是问题(或者,这实际上是我想要的)。”
答案 5 :(得分:1)
当编译器查看该行
时byte b=20;
它知道它在 b = 之后寻找一个字节。当它找到一个常量数值时,它在编译时知道它肯定会在 byte 的范围内,所以它会自动转换它。
何时看到该行
byte c=x;
它再一次在 c = 之后寻找一个字节,但是找不到已定义类型的变量,而不是找到一个数字常量,并且在编译时,不能确定它将在字节的范围内,因此您会收到错误。
答案 6 :(得分:0)
X定义为整数,而缩小则可能存在数据丢失,这就是编译错误的原因。请参阅jvm spec for conversions & promotions
答案 7 :(得分:0)
向上转换是自动的,因为向下转换或缩小(byte c=x;
)应该是明确的,因为它可能会导致程序员明确意识到的精度损失。要更正它,您需要进行显式转换byte c=(byte)x;