K.Sierra と B.Bates は著書「SCJP Study Guide」に次のように書いています。
"以下は正当byte b = 27;
ですが、コンパイラが自動的にリテラル値を 1 バイトに縮小するためです。つまり、コンパイラはキャストを挿入します。前のコードは次のコードと同じです:byte b = (byte) 27;
"
私の意見では、この説明は正しくありません。この 2 行のコードは同一ですか?
実際には
byte b = 27;
は単なる定数です。そして、このコードが有効である唯一の理由は、コンパイル時の定数の縮小です。したがって、キャストは必要ありません。絞り込むとき、コンパイラは、指定された値が変数の型に適合するかどうかをチェックするだけです。仕様には次のように書かれています。
変数の型がbyte、short、またはcharであり、定数式の値が変数の型で表現できる場合、縮小プリミティブ変換を使用できます。
2番目のケースでは
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!!
こう考えると、拡大縮小変換とキャストは根本的に違うと思います。しかし、さまざまなソースで、それらはしばしば同じ意味で使用されます。これは正しいです?暗黙の縮小変換の場合、キャストはカバーの下で発生しますか?
上記の本で説明されている状況でのコンパイラの実際の動作を説明できる人はいますか?