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 List
es una interfaz. Por lo tanto, podría tener una subclase de una Date
que realmente implemente List
disfrazada como List
aquí, y luego lanzarla Date
estarí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 S
de referencia a tipo de referencia T
si se cumple todo lo siguiente :
- [...]
- Se aplica uno de los siguientes casos :
- [...]
S
es un tipo de interfaz, T
es un tipo de clase y T
no nombra una final
clase.
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.
List
aquí.Date d = (Date) new Object();