Актерское это технически возможно. Javac не может легко доказать, что это не так в вашем случае, и JLS фактически определяет это как допустимую Java-программу, поэтому пометка ошибки будет неправильной.
Это потому, что Listэто интерфейс. Таким образом, у вас может быть подкласс класса a, Dateкоторый на самом деле реализует Listзамаскированный как 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();