La ragione per il primo risultato è che il metodo getClass
ha la seguente firma in Java
public final Class<?> getClass()
che eredita Scala. Mentre noi sappiamo che se chiamiamo getClass
su un riferimento di tipo T della firma potrebbe essere
public final Class<? extends T> getClass()
il compilatore non lo fa. Si potrebbe immaginare che qualche estensione lingua per fornire un tipo speciale che rappresenta il tipo statico del ricevitore che permetta
public final Class<? extends Receiver> getClass()
o una sorta di involucro speciale nel compilatore per getClass
. Sembra infatti che Snoracle Java sia davvero un caso speciale getClass
ma non sono sicuro che sia richiesto dalla specifica del linguaggio Java. Tuttavia, se si dispone di un riferimento di un particolare tipo statico T, non c'è motivo per cui non si possa fare l'equivalente T.class
(java) o classOf[T]
(scala). In altre parole tale estensione non porterebbe alcun potere espressivo maggiore ma complicherebbe l'implementazione della lingua.
Per quanto riguarda il "cast di tempo compilato" rispetto al "cast" statico ", non c'è davvero alcuna differenza. Sarebbe corretto per un compilatore di desugar x.asInstanceOf[T]
a classOf[T].cast(x)
.
Qualsiasi lingua con sottotipo ha la possibilità che il tipo di riferimento noto staticamente sia meno specifico del tipo del valore a cui fa riferimento. Le lingue con sistemi di tipo statico che non hanno sottotipi di solito non hanno un concetto di tipi di runtime in quanto esiste un solo tipo effettivo che risiede in un determinato tipo di nome. In questi linguaggi i tipi vengono cancellati in fase di esecuzione, nello stesso modo in cui i parametri di tipo vengono cancellati sulla JVM.
Spero che questo aiuti a comprendere i tipi di riferimenti statici rispetto al tipo di valori di runtime.
fonte
2011-01-26 15:25:54