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 List
jest interfejsem. Więc możesz mieć podklasę, Date
która faktycznie implementuje się w List
przebraniu, tak jak List
tutaj - a następnie rzutowanie na Date
był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 S
do typu odniesienia T
, jeśli wszystkie z poniższych są prawdziwe :
- [...]
- Obowiązuje jeden z następujących przypadków :
- [...]
S
jest typem interfejsu, T
jest typem klasy i T
nie nazywa final
klasy.
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.
List
tu nic specjalnego .Date d = (Date) new Object();