Domanda

import java.util.Collection;


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

        s = (Test) c;
    }
}

Nell'esempio di codice sopra, sto lanciando un oggetto di raccolta su un oggetto Test. (ignorando il puntatore null). Test ha nessuna relazione con Collection, tuttavia questo programma supererà tutti i controlli in fase di compilazione.

Mi chiedo perché sia ??così. La mia ipotesi è che le interfacce vengano ignorate perché troppo complicate. Non hanno un super-tipo comune e ogni classe può implementare diverse interfacce, quindi la gerarchia di classi / interfacce sarebbe troppo complicata per effettuare ricerche efficienti?

A parte questo motivo, però, sono perplesso. Qualcuno lo sa ?!

È stato utile?

Soluzione

" non finale " è una parola chiave qui. Potresti avere un'altra lezione

public class Test2 extends Test implements Collection

la cui istanza finirà per essere assegnata a s rendendo un cast perfettamente legale.

Altri suggerimenti

Perché una sottoclasse di Test può potenzialmente essere anche un sottotipo di Collection ! Le specifiche del linguaggio sono progettate per essere un po 'flessibili per consentire cast che possono essere verificati in fase di esecuzione.

Possiamo vederlo da una prospettiva diversa: qualsiasi classe non finale può essere trasmessa a QUALSIASI interfaccia

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; }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top