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