Implementazione di test di istanza in Java, C ++, C #

1

Per motivi di curiosità e per capire cosa comportano in un programma, sono curioso di sapere come funziona il test delle istanze ( instanceof / is / usando dynamic_cast in c ++). Ho provato a google (in particolare per java) ma le uniche pagine che vengono visualizzate sono tutorial su come utilizzare l'operatore.

In che modo le implementazioni variano tra quelle lingue? Come trattano le classi con le stesse firme?

Inoltre, mi è venuto in mente che usare test di istanza è un marchio di design scadente. Perché è esattamente questo? Quando è applicabile, instanceof dovrebbe essere ancora utilizzato in metodi come .equals() e tale diritto?

Ci stavo pensando anche a questo nel contesto della gestione delle eccezioni, ancora una volta in particolare in Java. Quando hai più istruzioni di catch , come funziona? Questa istanza è stata testata o è stata appena risolta durante la compilazione in cui ogni eccezione generata sarebbe stata utilizzata?

    
posta Jake 18.08.2014 - 04:27
fonte

1 risposta

4

I'm curious as to how instance testing (instanceof/is/using dynamic_cast in c++) works

In Java, ogni oggetto memorizza un puntatore al suo tipo. Ogni tipo conosce i suoi tipi principali, quindi è semplice enumerare tutti i tipi di antenati. x instanceof T se incontriamo T durante la ricerca.

Analogamente, in C ++, gli oggetti delle classi con metodi virtuali memorizzeranno un puntatore a type_info :

Every virtual table shall contain one entry that is a pointer to an object derived from std::type_info. (source)

(Questo è tuttavia specifico per gcc; non conosco altri compilatori.)

Also, it's been drilled into my head that using instance testing is a mark of bad design. Why exactly is this? When is that applicable, instanceof should still be used in methods like .equals() and such right?

L'idea è che, quando possibile, è preferibile utilizzare il polimorfismo piuttosto che controllare sottotipi specifici. Tende ad essere più elegante e non c'è alcuna possibilità di dimenticare di aggiornare i controlli dei sottotipi quando aggiungiamo un nuovo sottotipo.

Esempio totalmente forzato: diciamo che abbiamo Animal con sottotipi Lion , ecc. Se vogliamo verificare se Animal a è un carnivoro, potremmo scrivere a instanceof Lion || a instanceof Bear || ... , ma sarebbe più pulito e più sicuro da aggiungere un abstract boolean isCarnivore(); in Animal .

Ma sono d'accordo, instanceof è ancora appropriato in equals poiché l'API ci obbliga a gestire Object s.

When you have mutliple catch statements, how does that work? Is that instance testing or is it just resolved during compilation where each thrown exception would go to?

In Java, non è possibile per un compilatore precompilare il percorso di ciascuna eccezione perché è possibile caricare nuove classi di eccezioni in fase di runtime.

Il compilatore genera una "tabella di eccezioni" per ogni blocco try / catch, in cui una riga nella tabella contiene un tipo di eccezione e un offset pc che dovrebbe essere applicato se si verifica tale eccezione. Ma se dichiari catch (IOException) , la tabella delle eccezioni conterrà solo IOException , non sottoclassi come EOFException . Un controllo instanceof -like deve essere eseguito in fase di esecuzione per verificare se un'eccezione generata è IOException .

    
risposta data 18.08.2014 - 07:35
fonte

Leggi altre domande sui tag