キャストは技術的に可能です。あなたの場合はそうではないことをjavacで簡単に証明することはできません。JLSはこれを有効なJavaプログラムとして実際に定義しているため、エラーのフラグ付けは正しくありません。
これはListがインターフェイスであるためです。したがってDate、実際にここのようにList偽装して実装するaのサブクラスを作成し、ListそれをキャストしてDate完全に問題ないようにすることができます。例えば:
public class SneakyListDate extends Date implements List<Foo> {
...
}
その後:
List<Foo> list = new SneakyListDate();
Date date = (Date) list; // This one is valid, compiles and runs just fine
そのようなシナリオを検出することは常に可能であるとは限りません。インスタンスがたとえばメソッドからのものである場合は、ランタイム情報が必要になるためです。そして、たとえそれがあったとしても、それはコンパイラーにとってはるかに多くの努力を必要とするでしょう。コンパイラーは、クラスツリーがまったく一致する方法がないために絶対に不可能であるキャストのみを防止します。見られるように、ここではそうではありません。
JLSでは、コードが有効なJavaプログラムである必要があることに注意してください。では5.1.6.1。ナローイング参照変換を許可します:
次のすべてが当てはまる場合、参照型から参照型Sへのナローイング参照変換が存在します。T
- [...]
- 一次例が適用されます:
- [...]
Sはインターフェース型でTあり、クラス型でありT、finalクラスに名前を付けません。
そのため、コンパイラがあなたのケースが実際には不可能であると証明できたとしても、JLSがそれを有効なJavaプログラムとして定義しているため、エラーにフラグを立てることはできません。
警告の表示のみが許可されます。
Listここで特別なことはありません。Date d = (Date) new Object();