Perché viene compilato quando si esegue il casting su un’interfaccia non correlata?

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

Se il codice precedente è compilato ed eseguito, il risultato è un ClassCastException a printable = (Printable)blackInk; . Ma, se Printable viene modificato in una class, non viene compilato perché non è ansible eseguire il cast di blackInk su Printable. Perché viene compilato quando Printable è un’interfaccia?

Il compilatore non sa che questo non funzionerà: potresti avere una sottoclass di BlackInk che implementa Printable. Quindi il cast andrebbe bene.

In situazioni in cui il compilatore sa che non funzionerà, si verificherà un errore.

Ad esempio, se si esegue BlackInk final (in modo che non ci possano essere sottoclassi) si ottiene un errore.

In base alla sezione sulle specifiche del linguaggio Java: 5.5.1 Casting di tipo di riferimento :

Per un riferimento in fase di compilazione, tipo S (origine) e un tipo di riferimento tipo compilazione T (destinazione); Durante la conversione del cast da S a T , Se S è un tipo di class

  • Se T è un tipo di Class :

    1. Quindi T è un sottotipo di S o S è un sottotipo di T In caso contrario, si verifica un errore di compilazione.
    2. se esiste un supertipo X di T e un supertipo Y di S , tale che sia X che Y sono tipi parametrici distinti e che le cancellazioni di X e Y sono le stesse, si verifica un errore in fase di compilazione .

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

    1. Se S non è una class final , allora, se esiste un supertipo X di T , e un supertipo Y di S , tale che sia X che Y sono tipi parametrici distinti e che le cancellazioni di X e Y sono le stesse, si verifica un errore in fase di compilazione . Altrimenti, il cast è sempre legale al momento della compilazione ( perché anche se S non implementa T , una sottoclass di S potrebbe )
    2. Se S è una class finale, allora S deve implementare T, oppure si verifica un errore in fase di compilazione.

Questo vale per il tuo caso, anche se il cast di class viene rilevato in fase di compilazione, la trasmissione dell’interfaccia viene rilevata in runtime .

Il casting del tipo avviene in run time di run time (ricorda il polimorfismo del tempo di esecuzione). Al momento della compilazione il compilatore non vede nulla di sbagliato nel codice e compila e in fase di esecuzione prova a digitare il cast blackink in printable e non è in grado di farlo perché il blackink non implementa la printable , da qui l’errore.