Le casting est techniquement possible. Il n'est pas facile de prouver par javac que ce n'est pas le cas dans votre cas et le JLS le définit en fait comme un programme Java valide, donc signaler une erreur serait incorrect.
C'est parce que List
c'est une interface. Donc, vous pourriez avoir une sous-classe d'un Date
qui implémente réellement List
déguisé comme List
ici - et le lancer Date
serait parfaitement correct. Par exemple:
public class SneakyListDate extends Date implements List<Foo> {
...
}
Et alors:
List<Foo> list = new SneakyListDate();
Date date = (Date) list; // This one is valid, compiles and runs just fine
La détection d'un tel scénario n'est pas toujours possible, car elle nécessiterait des informations d'exécution si l'instance provient, par exemple, d'une méthode à la place. Et même si cela nécessiterait beaucoup plus d'efforts pour le compilateur. Le compilateur empêche uniquement les transtypages qui sont absolument impossibles car il n'y a aucun moyen pour l'arbre de classe de correspondre du tout. Ce qui n'est pas le cas ici, comme on le voit.
Notez que le JLS requiert que votre code soit un programme Java valide. Au 5.1.6.1. Conversion de référence restreinte autorisée, il est dit:
Une conversion de référence rétrécie existe du type référence au type S
référence T
si toutes les conditions suivantes sont remplies :
- [...]
- L'un des cas suivants s'applique :
- [...]
S
est un type d'interface, T
est un type de classe et T
ne nomme pas de final
classe.
Ainsi, même si le compilateur peut comprendre que votre cas est réellement impossible, il n'est pas autorisé de signaler une erreur car le JLS le définit comme un programme Java valide.
Il serait seulement permis d'afficher un avertissement.
List
ici.Date d = (Date) new Object();