2011-02-10 4 views
11

Sto lavorando alla mia implementazione della JVM e sono arrivato all'istruzione checkcast. La documentazione completa è on this page. Sono curioso perché quando si enumerano le regole per come funziona il cast, una condizione che viene controllata è se il riferimento oggetto che viene controllato è di tipo interfaccia. Secondo la mia comprensione, questo non dovrebbe essere possibile; le interfacce non possono essere istanziate direttamente e qualsiasi oggetto che implementa un'interfaccia ha qualche altro tipo di classe concreta. Mi sto perdendo qualcosa?Confusione sull'istruzione bytecode checkcast?

risposta

20

Sembra che non eri l'unico confuso su questa definizione, questo post del blog ha una spiegazione: http://mbravenboer.blogspot.com/2008/12/why-jvm-spec-defines-checkcast-for.html

Si scopre che questo è davvero un caso `impossibile'. Il motivo per cui questo articolo è nella specifica , perché checkcast è ricorsivamente definito per gli array:

  • Se S è una classe che rappresenta il tipo di matrice SC [], cioè una serie di componenti di tipo SC, quindi:
  • ...
  • Se T è un tipo di matrice TC [], cioè, un array di componenti di tipo TC, quindi una delle seguenti deve essere true:
    • ...
    • TC e SC sono tipi di riferimento e il tipo SC può b Esegui il cast in TC mediante l'applicazione ricorsiva di queste regole.

Quindi, se si dispone di un oggetto di tipo List [] che è lanciato ad una collezione [], quindi le regole per ottenere checkcast ricorsivamente invocati per i tipi S = List e T = Collection. Si noti che List è un'interfaccia, ma un oggetto può avere tipo List [] in fase di esecuzione. Se non l'ho verificato con i manutentori della JVM Spec, ma per quanto posso vedere, questo è l'unico motivo per cui esiste la regola per i tipi di interfaccia.

+0

Grazie mille! Questo è esattamente il tipo di risposta che stavo cercando. – templatetypedef

+0

+1 brillante. :) – biziclop

-2

Se S è un tipo di interfaccia, quindi:

Se T è un tipo di classe, allora T deve essere oggetto (§2.4.7).
Se T è un tipo di interfaccia, allora T deve essere la stessa interfaccia di S o una superinterfaccia di S (§2.13.2).

Mi sembra chiaro: un'interfaccia può essere trasmessa su un'interfaccia estesa. Questo caso viene utilizzato ad esempio quando si chiama la serializzazione su DataInputStream: l'interfaccia DataInputStream implementa Serializable, quindi l'oggetto viene serializzato senza nemmeno sapere quale sia la classe implementata dell'oggetto.

+1

Penso che tu non abbia capito la domanda. Inoltre, [java.io.DataInputStream] (https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html) è una classe, non un'interfaccia. –