¿Por qué se comstack cuando se lanza a una interfaz no relacionada?

interface Printable {} class BlackInk {} public class Main { public static void main(String args[]) { Printable printable = null; BlackInk blackInk = new BlackInk(); printable = (Printable)blackInk; } } 

Si el código anterior se comstack y se ejecuta, el resultado es una ClassCastException en printable = (Printable)blackInk; . Pero, si Imprimible se cambia a una clase, no se comstack porque BlackInk no se puede convertir a Imprimible. ¿Por qué se comstack cuando Printable es una interfaz?

El comstackdor no sabe que esto no funcionará: podría tener una subclase de BlackInk que implemente Printable. Entonces el elenco estaría bien.

En situaciones donde el comstackdor sabe que no funcionará, obtendrá un error.

Por ejemplo, si hace que BlackInk sea final (para que no pueda haber subclases) se obtiene un error.

Según la sección de especificación del lenguaje Java: 5.5.1 Tipo de referencia Casting :

Para un tipo de referencia de tiempo de comstackción S (fuente) y un tipo de referencia de tipo de comstackción T (destino); Al convertir conversiones de S a T , si S es un tipo de class

  • Si T es un tipo de Class :

    1. Entonces, o bien T es un subtipo de S o S es un subtipo de T De lo contrario, se produce un error de tiempo de comstackción.
    2. si existe un supertipo X de T y un supertipo Y de S , de modo que tanto X como Y son tipos parametrizados claramente distintos, y que las borraduras de X e Y son las mismas, se produce un error de tiempo de comstackción .

       class S{} class T extends S{} //// S s = new S(); T t = (T)s; // run time ClassCastException will happen but no compile time error 
  • Si T es un tipo de Interface :

    1. Si S no es una clase final , entonces, si existe un supertipo X de T , y un supertipo Y de S , de modo que tanto X como Y son tipos parametrizados claramente distintos, y que las borraduras de X e Y son las mismas, se produce un error de tiempo de comstackción . De lo contrario, el elenco siempre es legal en tiempo de comstackción ( porque incluso si S no implementa T , una subclase de S podría )
    2. Si S es una clase final, entonces S debe implementar T o se produce un error en tiempo de comstackción.

Eso es para su caso, incluso si la conversión de clase se detecta en tiempo de comstackción, la conversión de interfaz se detecta en runtime de runtime .

La conversión de tipos ocurre en el run time (recuerda el polymorphism de tiempo de ejecución). En tiempo de comstackción, el comstackdor no ve nada incorrecto con el código y comstack, y en tiempo de ejecución intenta escribir blackink para printable y no puede hacerlo porque blackink no implementa printable , de ahí el error.