En el siguiente ejemplo, ¿por qué el compilador no informa de un error para la fundición x
a D
?
interface X {}
class C implements X {}
class D {}
public class CastIssue {
public static void main(String[] args) {
X x = new C();
// why is there no error here?
D d = (D) x;
}
}
Pero, si hacemos X
una clase, el compilador informa de un error:
class X {}
class C extends X {}
class D {}
public class CastIssue {
public static void main(String[] args) {
X x = new C();
// this gives a compile-time error
D d = (D) x;
}
}
Colada de X
que D
está permitido ya que es posible que un objeto que sea una instancia de ambos X
y D
. Por ejemplo:
class E extends D implements X {}
X x = new E();
D d = (D) x; // no problem here, because an X can be a D too
En su ejemplo, podemos determinar a partir de la secuencia de instrucciones que el reparto será fallar, pero Java no puede, porque no tiene en cuenta el flujo de control al determinar los tipos en tiempo de compilación.
Sin embargo, si X
es una clase, entonces ya X
y D
no tendría subclases comunes (Java no permite la herencia múltiple de clases), sería imposible que un objeto sea una instancia de ambas clases no relacionadas. En ese caso, el reparto no está permitido porque en base a los tipos en tiempo de compilación, el elenco nunca podría tener éxito (a menos que x
es null
).