Актерское это технически возможно. 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();