有人可以解释为什么以下编译:
final short s1 = 1;
final char c1 = 1;
byte b1 = s1;
byte b2 = c1;
但是以下内容(编译器错误消息为Type mismatch: cannot convert from short to byte
):
short s1 = 1;
char c1 = 1;
byte b1 = s1;
byte b2 = c1;
答案 0 :(得分:48)
答案在JLS - 5.2. Assignment Conversion:
..如果表达式是
byte
类型的常量表达式(§15.28),short
,char
或int
:
- 如果是,则可以使用缩小的基元转换 变量的类型是
byte
,short
或char
,以及 常量表达式可以在变量的类型中表示。
当你写:
final short s1 = 1;
表达式的值在编译时是已知,因为它无法更改,所以不需要强制转换。
在你的第二个片段中,该值在编译时是未知的 - 它是在运行时中计算的,因此你需要一个显式的强制转换。
如果您尝试编译以下代码:
final byte b1 = 200;
final byte b2 = 200;
byte sum = b1 + b1;
您将收到编译错误,因为右侧的值已知到编译器并且它知道总和不能适合{{1} }。
答案 1 :(得分:17)
在第一个示例中,编译器知道s1
和c1
永远不会改变,并且它们的最终值(1
)符合byte
。
在第二种情况下,编译器担心当s1
和c1
在 0..255
-128..127
之外时会发生什么情况? byte
变量,并警告您它不安全。
如果你明确地将它们视为balalaika在评论中所建议的那样,那么编译器就会感到宽慰,因为你似乎知道自己在做什么(或者至少,如果事情发生了,它会有人责备),让你这样做