Obsada jest technicznie możliwa. Javac nie może łatwo udowodnić, że tak nie jest w twoim przypadku, a JLS faktycznie definiuje to jako prawidłowy program Java, więc oznaczenie błędu byłoby nieprawidłowe.
To dlatego, że Listjest interfejsem. Więc możesz mieć podklasę, Datektóra faktycznie implementuje się w Listprzebraniu, tak jak Listtutaj - a następnie rzutowanie na Datebyłoby całkowicie w porządku. Na przykład:
public class SneakyListDate extends Date implements List<Foo> {
...
}
I wtedy:
List<Foo> list = new SneakyListDate();
Date date = (Date) list; // This one is valid, compiles and runs just fine
Wykrywanie takiego scenariusza może nie zawsze być możliwe, ponieważ wymagałoby to informacji o środowisku wykonawczym, jeśli instancja pochodzi na przykład z metody. I nawet jeśli kompilator wymagałby znacznie więcej wysiłku. Kompilator zapobiega tylko rzutowaniom, które są absolutnie niemożliwe z powodu braku możliwości dopasowania drzewa klas. Jak widać, w niniejszym przypadku tak nie jest.
Pamiętaj, że JLS wymaga, aby kod był prawidłowym programem Java. W 5.1.6.1. Dozwolona zawężająca się konwersja odniesienia mówi:
Konwersja referencyjny zwężenie istnieje od rodzaju odniesienia Sdo typu odniesienia T, jeśli wszystkie z poniższych są prawdziwe :
- [...]
- Obowiązuje jeden z następujących przypadków :
- [...]
Sjest typem interfejsu, Tjest typem klasy i Tnie nazywa finalklasy.
Więc nawet jeśli kompilator może zorientować się, że twoja sprawa jest rzeczywiście niemożliwa do udowodnienia, nie jest dozwolone oznaczenie błędu, ponieważ JLS definiuje go jako prawidłowy program Java.
Dopuszczalne byłoby jedynie wyświetlenie ostrzeżenia.
Listtu nic specjalnego .Date d = (Date) new Object();