为什么赋值’int constant – > byte variable’有效,但’long constant – > int variable’不是?

我有这段代码:

int i = 5l; // not valid (compile error) byte b = 5; // valid 

你怎么看待这件事?

为什么?

这在JLS#5.2(分配转换)中定义 :

如果表达式是byte,short,char或int类型的常量表达式(第15.28节),如果变量的类型是byte,short或char,则可以使用缩小的原语转换,以及常量表达式的值可以表示变量的类型。

所以:

 byte b = 5; //ok: b is a byte and 5 is an int between -128 and 127 byte b = 1000; //not ok: 1000 is an int but is not representable as a byte (> 127) byte b = 5L; //not ok: 5L is a long (and not a byte, short, char or int) int i = 5L; //not ok: i is not a byte, short or char int i = 5; byte b = i; //not ok: i is not a constant final int i = 5; byte b = i; //ok: i is a constant and b is a byte 

只是假设在这里因为不太可能有明确的答案。

对于

 int i = 5l; 

编译器假设你有一个很好的理由你写了5l而不是5 ,所以这是一个错误。

对于

 byte b = 5; 

没有byte文字的写法5,因此每次写入(byte) 5并且事实上它容易出错将是不必要的迂腐。

 byte b = 222; // is an error byte b = (byte) 222; // is NOT an error 

语言规范允许(注意5,127或128是整数文字):

  byte b = 127; 

这会产生错误:

  byte b = 128; 

这称为隐式缩小基元转换,JLS允许:

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

如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

所以,由于上面的陈述,下面是编译器错误

 int i = 5l; 

5l是long,而不是byte,short,char或int类型的常量表达式(第15.28节) 。 它也不正确,因为它是一个int,因为变量的类型是byte,short或char

在第一种情况下

 int i = 5l; // trying to allocate 64bits in 32 bits space. Err 

在哪里

 byte b = 5; // byte can represented in a range is -128 to 127. Compiles fine 

我现在想到的一件事是为什么int i = 5l; 是不可能的,因为long的范围大于int范围,因此将long值放在int的变量中是不可能的。

int范围: -2147483648 … 2147483648 ,长距离: -2 ^ 63 … 2 ^ 63-1

根据我的理解,

因为你必须将类型long转换为int,对于第一个选项,即

 int i = (int) 5l; 

在第二种情况下,由于对byte的赋值与赋值为int相同,

你认为我在这里为int赋值int值

 byte b= 5; ???? 

不,它不是,它将值作为字节本身,因为字节的范围从-128到127,

有关详细信息,请参阅此处