String
をJava.util.Date
にキャストしようとすると、Javaコンパイラーがエラーをキャッチします。それで、コンパイラーが以下のエラーをフラグしないのはなぜですか?
List<String> strList = new ArrayList<>();
Date d = (Date) strList;
もちろん、JVMは実行時にClassCastException
をスローしますが、コンパイラーはフラグを立てません。
動作は、javac 1.8.0_212および11.0.2と同じです。
コンパイル時の参照型
S
(ソース)とコンパイル時の参照型T
(ターゲット)が指定されている場合、以下の規則によりコンパイル時エラーが発生しない場合、キャスト変換はS
からT
に変換されます。[...]
S
がインターフェース型の場合:
[...]
T
が最終でないクラスまたはインタフェースタイプの場合は、X
のスーパータイプT
が存在する場合、及びY
のスーパータイプS
、X
とY
両方が証明可能異なるパラメータ化された型であるように、及びX
とY
の消去その同じ場合、コンパイル時エラーが発生します。それ以外の場合、キャストはコンパイル時に常に有効です(
T
がS
を実装していない場合でも、T
のサブクラスである可能性があります)。
List<String>
はS
で、Date
はT
です。