为什么分配short to byte仅在short是final时工作?

MAT*_*000 37 java

有人可以解释为什么以下编译:

final short s1 = 1;
final char c1 = 1;
byte b1 = s1;
byte b2 = c1;
Run Code Online (Sandbox Code Playgroud)

但是以下没有(编译器错误消息是Type mismatch: cannot convert from short to byte):

short s1 = 1;
char c1 = 1;
byte b1 = s1;
byte b2 = c1;
Run Code Online (Sandbox Code Playgroud)

Mar*_*oun 48

答案在JLS - 5.2中.作业转换:

..如果表达式是一个常量表达式(§15.28类型的)byte, short,char,或int:

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

当你写:

final short s1 = 1;
Run Code Online (Sandbox Code Playgroud)

表达式的值在编译时是已知的,因为它无法更改,所以不需要强制转换.

在您的第二个片段中,该值在编译时是未知的 - 它在运行时进行评估,因此您需要显式强制转换.


如果您尝试编译以下代码:

final byte b1 = 200;
final byte b2 = 200;
byte sum = b1 + b1;
Run Code Online (Sandbox Code Playgroud)

您将收到编译错误,因为编译器已知右侧的值,并且它知道总和不适合a byte.


Ama*_*dan 17

在第一个示例中,编译器知道s1并且c1永远不会更改,并且它们的最终值(1)适合byte.

在第二,编译器会担心发生什么,如果s1c1在外面时,他们被分配到一个变量,并警告你,这是不安全的.0..255 -128..127byte

如果你明确地将它们视为balalaika在评论中的建议,编译器会感到宽慰的是你似乎知道你正在做什么(或者至少,如果事情发生了,它会有人责备),并让你这样做.

  • 我不能.简单的解释是:JLS只允许它用于`byte`,`short`,`char`和`int`(很棒的发现,Maroun Maroun - +1!).但是,但没有提供任何解释,或省略'long`.我的解释对我有意义; 但我无法弄清楚为什么不允许`long`以同样的方式行事. (5认同)