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 Listc'est une interface. Donc, vous pourriez avoir une sous-classe d'un Datequi implémente réellement Listdéguisé comme Listici - et le lancer Dateserait 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 Sréférence Tsi toutes les conditions suivantes sont remplies :
- [...]
- L'un des cas suivants s'applique :
- [...]
Sest un type d'interface, Test un type de classe et Tne nomme pas de finalclasse.
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.
Listici.Date d = (Date) new Object();