Die Besetzung ist technisch möglich. Javac kann nicht einfach beweisen, dass dies in Ihrem Fall nicht der Fall ist, und das JLS definiert dies tatsächlich als gültiges Java-Programm. Daher wäre es falsch, einen Fehler zu kennzeichnen.
Dies liegt daran, dass Listes sich um eine Schnittstelle handelt. Sie könnten also eine Unterklasse von a haben Date, die tatsächlich Listwie Listhier getarnt implementiert - und dann Datewäre es vollkommen in Ordnung, sie zu besetzen. Zum Beispiel:
public class SneakyListDate extends Date implements List<Foo> {
...
}
Und dann:
List<Foo> list = new SneakyListDate();
Date date = (Date) list; // This one is valid, compiles and runs just fine
Das Erkennen eines solchen Szenarios ist möglicherweise nicht immer möglich, da Laufzeitinformationen erforderlich sind, wenn die Instanz beispielsweise von einer Methode stammt. Und selbst wenn, würde es viel mehr Aufwand für den Compiler erfordern. Der Compiler verhindert nur Casts, die absolut unmöglich sind, da der Klassenbaum überhaupt nicht übereinstimmen kann. Was hier nicht der Fall ist, wie man sieht.
Beachten Sie, dass das JLS erfordert, dass Ihr Code ein gültiges Java-Programm ist. In 5.1.6.1. Zulässige schmale Referenzkonvertierung heißt es:
Eine verengende Referenzkonvertierung von Referenztyp Szu Referenztyp ist vorhanden, Twenn alle der folgenden Bedingungen erfüllt sind :
- [...]
- Einer der folgenden Fälle gilt :
- [...]
Sist ein Schnittstellentyp, Tist ein Klassentyp und Tbenennt keine finalKlasse.
Also auch wenn der Compiler könnte herausfinden , dass Ihr Fall tatsächlich nachweislich unmöglich ist, darf er keinen Fehler melden, da das JLS ihn als gültiges Java-Programm definiert.
Es darf nur eine Warnung angezeigt werden.
List.Date d = (Date) new Object();