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 List
es sich um eine Schnittstelle handelt. Sie könnten also eine Unterklasse von a haben Date
, die tatsächlich List
wie List
hier getarnt implementiert - und dann Date
wä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 S
zu Referenztyp ist vorhanden, T
wenn alle der folgenden Bedingungen erfüllt sind :
- [...]
- Einer der folgenden Fälle gilt :
- [...]
S
ist ein Schnittstellentyp, T
ist ein Klassentyp und T
benennt keine final
Klasse.
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();