私はJava言語仕様、第3版を読んでいて、仕様とjavacコンパイラの実装との間の不一致であると私が思うものを見つけました。同じ不一致がEclipseコンパイラーにも存在します。
セクション15.16では、キャスト式について説明しています。引数タイプをキャスト変換(セクション5.5)でキャストタイプに変換できない場合は、コンパイル時エラーになるはずです。
オペランドのコンパイル時型が、キャスト変換の規則(§5.5)に従ってキャスト演算子によって指定された型にキャストされない場合は、コンパイル時エラーになります。それ以外の場合、実行時に、オペランド値は、キャスト演算子によって指定されたタイプに変換をキャストすることによって(必要に応じて)変換されます。
セクション5.5では、キャスト変換について説明します。許可されている変換タイプのリストが表示されます。特にリストに含まれていないのは、「開開変換とそれに続く拡大/縮小プリミティブ変換」です。ただし、その正確な変換シーケンスは、javacコンパイラー(およびEclipseコンパイラー)によって許可されているようです。例えば:
long l = (long) Integer.valueOf(45);
...正常にコンパイルされます。(問題のあるキャストはへのキャストlong
です。引数はタイプであるため、変換にはボックス化を解除してから、プリミティブ変換を拡張java.lang.Integer
する必要があります)。int
byte
同様に、JLSによると、からへのキャストは不可能です。これは、( 5.1.4char
によると)プリミティブ変換の拡大とプリミティブ変換の縮小が必要なためです。ただし、このキャストはコンパイラーによっても許可されます。
誰かが私を啓発できますか?
編集:これを求めて以来、私はOracleにバグレポートを提出しました。彼らの反応は、これが「JLSのグリッチ」であるというものです。