El reparto es técnicamente posible. Javac no puede demostrar fácilmente que no es así en su caso y el JLS en realidad define esto como un programa Java válido, por lo que marcar un error sería incorrecto.
Esto se debe a que Listes una interfaz. Por lo tanto, podría tener una subclase de una Dateque realmente implemente Listdisfrazada como Listaquí, y luego lanzarla Dateestaría perfectamente bien. Por ejemplo:
public class SneakyListDate extends Date implements List<Foo> {
...
}
Y entonces:
List<Foo> list = new SneakyListDate();
Date date = (Date) list; // This one is valid, compiles and runs just fine
La detección de este escenario podría no ser siempre posible, ya que requeriría información de tiempo de ejecución si la instancia proviene, por ejemplo, de un método. E incluso si, requeriría mucho más esfuerzo para el compilador. El compilador solo evita los lanzamientos que son absolutamente imposibles debido a que no hay forma de que el árbol de clases coincida en absoluto. Que no es el caso aquí, como se ve.
Tenga en cuenta que JLS requiere que su código sea un programa Java válido. En 5.1.6.1. Conversión de referencia de estrechamiento permitida dice:
Existe una conversión de referencia de reducción de tipo Sde referencia a tipo de referencia Tsi se cumple todo lo siguiente :
- [...]
- Se aplica uno de los siguientes casos :
- [...]
Ses un tipo de interfaz, Tes un tipo de clase y Tno nombra una finalclase.
Entonces, incluso si el compilador pudiera descubrir que su caso es realmente imposible, no está permitido marcar un error porque el JLS lo define como un programa Java válido.
Solo se le permitiría mostrar una advertencia.
Listaquí.Date d = (Date) new Object();