Pregunta

import java.util.Collection;


public class Test
{
    public static void main(String[] args)
    {
        Collection c = null;
        Test s = null;

        s = (Test) c;
    }
}

En el ejemplo de código anterior, estoy enviando un objeto de colección a un objeto Test. (ignorando el puntero nulo). La prueba tiene relación no con la Colección, sin embargo, este programa pasará todas las comprobaciones en tiempo de compilación.

Me pregunto por qué es esto. Mi suposición es que las interfaces se ignoran porque son demasiado complicadas. No tienen un supertipo común y cada clase puede implementar varias interfaces, por lo que la jerarquía de clase / interfaz sería demasiado complicada para buscar de manera eficiente.

Aparte de eso, estoy perplejo. ¿Alguien sabe ?!

¿Fue útil?

Solución

" No final " Es una palabra clave aquí. Puedes tener otra clase

public class Test2 extends Test implements Collection

cuya instancia terminará siendo asignada a s haciendo que un reparto sea perfectamente legal.

Otros consejos

¡Porque una subclase de Test también puede ser un subtipo de Collection ! La especificación del lenguaje está diseñada para ser un poco flexible para permitir conversiones que se pueden verificar en tiempo de ejecución.

Podemos verlo desde una perspectiva diferente: cualquier clase no final se puede convertir a CUALQUIER interfaz

import java.util.function.Predicate;

public class Test {
    public static void main(String[] args) {
        Predicate check;

        try {
            /*It's ok to cast to ANY interface because the Base class is not final.
              Java compiler allows it because some class may extend it 
              and implement the predicate interface. 
              So java compiler can check it only at runtime time not compile time.             
            */
            check = (Predicate)(new Base());

            /*
             Java compiler doesn’t allow it because the BaseFinal is final.
             And it means that no one can extend it and implement interface Predicate. 
             So java compiler can check it at compile time.
            */
            //check = (Predicate)(new BaseFinal()); 
        } catch (ClassCastException e) {
            System.out.println("Class Cast Exception");
        }
        check = (Predicate)(Base)(new Child());
    }    
}
final class BaseFinal {};

class Base {}

class Child extends Base implements Predicate {
    public boolean test(Object t) { return true; }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top