K.Sierra 和 B.Bates 在他们的《SCJP 学习指南》一书中写道
"下面是合法的byte b = 27;
,但仅仅是因为编译器自动将文字值缩小到一个字节。换句话说,编译器进行了强制转换。前面的代码与下面的代码相同:byte b = (byte) 27;
"
在我看来,这种解释是不正确的。这两行代码是否相同?
实际上
byte b = 27;
只是一个常数。而常量的编译时变窄是这段代码有效的唯一原因。所以不需要演员表。缩小范围时,编译器只检查指定的值是否适合变量的类型。规范说:
如果变量的类型是byte、short或char,并且常量表达式的值可以用变量的类型表示,则可以使用缩小原语转换。
在第二种情况下
byte b = (byte) 27;
强制转换确实在运行时发生,并且原始值是根据特定规则计算的。编译器不关心原始类型的兼容性。例如
byte b = 5.0; // compile error
byte b = 277777777; // compile error
byte b = (byte) 5.0; // valid!
byte b = (byte) 277777777; // valid!!
这让我觉得扩大/缩小转换和铸造是根本不同的。但在各种来源中,它们经常互换使用。这个对吗?在隐式缩小转换的情况下是否会发生强制转换?
任何人都可以解释编译器在上述书中描述的情况下的真实行为吗?