java中的隐式缩小规则

java中的隐式缩小规则,java,narrowing,Java,Narrowing,我不相信java编译器在上面代码的第三行中应用的缩小规则 请帮助我理解这个缩小规则背后的逻辑。文本0L上的L后缀使该文本的类型长(64位有符号整数) 根据Java语言的规则,没有从long到byte的隐式收缩 请参阅Java语言规范: 此外,如果表达式是byte、short、char或int类型的常量表达式(§15.28): 如果变量的类型是字节、短或字符,并且常量表达式的值可以用变量的类型表示,则可以使用缩小原语转换 请注意,常量表达式的类型不包括long有两种方法可以将基本数据类型强制转

我不相信java编译器在上面代码的第三行中应用的缩小规则


请帮助我理解这个缩小规则背后的逻辑。

文本
0L
上的
L
后缀使该文本的类型
长(64位有符号整数)

根据Java语言的规则,没有从
long
byte
的隐式收缩

请参阅Java语言规范:

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

  • 如果变量的类型是
    字节
    字符
    ,并且常量表达式的值可以用变量的类型表示,则可以使用缩小原语转换

请注意,常量表达式的类型不包括
long

有两种方法可以将基本数据类型强制转换为另一种。显性和隐性

隐式强制转换,如您的情况
字节b=0L提供编译错误,因为可能会丢失信息

如果您这样更改它:

byte b = 0xFFFFFFFF; //OK, because integer -1 sits between -128 and 127, FINE!!
char ch = 0xFFFFFFFF; //Not OK, because integer -1 does not sit between 0 and 65535, FINE!!
byte b = 0L; //Compiler says Not OK? But long integer 0 sits between -128 and 127?

那么就不会有编译器错误,因为您明确地告诉编译器要进行转换。

在我上面的代码中,无论哪个规则将整数缩小到字节,同一规则不能应用于长(64位)到字节(8位)?@overexchange第一行是数字文字-它可以分配给
字节。第三行是
长的
,因为您明确要求了一行。
长的
永远不能分配给
字节
。有人可能会说,编译器可以检查编译时常量,但它不能-这是规则。@overexchange添加了链接和来自JLS的相关引用。我已经通过了缩小规则。我想说的是,这对我来说毫无意义。为什么?若整数缩窄到字节,那个么长整数应该缩窄到字节,否则你们就迫使我在并没有概念逻辑的情况下把这些规则拼凑起来。这太难了@过度交流很难说为什么规则是这样的;如果您真的想知道,您必须询问Java语言的设计者。在这种情况下,没有真正的硬技术原因来解释为什么它应该是这样的,这只是设计师选择规则的方式。没有什么比显式和隐式铸造更好的了。java中有加宽(隐式)、缩小(隐式)和强制转换(显式)
byte b=(byte)0L;