Pergunta

import java.util.Collection;


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

        s = (Test) c;
    }
}

No exemplo de código acima, eu estou lançando um objeto de coleção para um objeto de teste. (Ignorando o ponteiro nulo). Teste tem não relação com a coleção que seja, ainda este programa vai passar todas as verificações de tempo de compilação.

Eu estou querendo saber o porquê disso. Minha suposição é que as interfaces são ignorados porque eles são muito complicados. Eles não têm super-tipo comum e cada classe pode implementar várias interfaces, de modo a hierarquia de classes / Interface seria muito complicado para procurar de forma eficiente?

Além disso razão pela qual eu estou perplexo embora. Alguém sabe?!

Foi útil?

Solução

"não-final" é uma palavra-chave aqui. Você pode ter uma outra classe

public class Test2 extends Test implements Collection

cuja instância vai acabar sendo atribuído a s fazendo um elenco perfeitamente legal.

Outras dicas

Como uma subclasse de Test pode ser potencialmente um subtipo de Collection bem! A especificação de linguagem é projetado para ser um pouco flexível para moldes de licenças que podem ser verificadas em tempo de execução.

Nós podemos vê-lo a partir de uma perspectiva diferente: qualquer classe non final pode ser escalado a qualquer interface

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top