2009-03-10 17 views
12

C'è qualcosa di difficile che dovrei sapere su instanceof? Sto passando una lista di oggetti attraverso alcuni metodi e testando se questi oggetti implementano un'interfaccia particolare usando instanceof. In alcuni casi, instanceof identifica correttamente gli oggetti come l'implementazione dell'interfaccia, in altri casi no. Sembra che mi dia risultati incoerenti sullo stesso oggetto in posti diversi. C'è qualche trucco/trucco di cui dovrei essere a conoscenza qui?restituisce risultati inconsistenti per il rilevamento di interfacce?

In previsione di commenti si potrebbe avere:

1) So instanceof è di cattivo gusto. Sto lavorando con una gerarchia di oggetti tutt'altro che perfetta che non può essere modificata, e questa è la cosa meno brutta che posso pensare di fare.

2) Sto lavorando per creare un esempio di codice, ma ho bisogno di semplificare molto il mio codice se ho intenzione di incollare qualcosa di utile qui. Nel frattempo, se l'hai già visto prima e puoi far luce, per favore fallo.

+0

Qualche possibilità di ottenere un esempio di codice? – Rontologist

+0

Solo un'ipotesi, ma è abbastanza probabile che la semplificazione del codice per pubblicare un campione possa esporre il problema. instanceof è un operatore, quindi dovrebbe sempre funzionare allo stesso modo. –

+0

Sì, la mia ipotesi è che se semplificherò abbastanza il mio codice da incollare per tutti gli utenti utili, troverò il bug e non sarà necessario :) – morgancodes

risposta

4

L'unica cosa che so è che null è instanceof nessun tipo.

+0

1 caso cool edge! – HDave

+0

Ho avuto un incredibile momento di realizzazione qui. –

13

Si sta caricando qualsiasi tipo in modo dinamico, potenzialmente da diversi classloader? L'unica volta che ho visto risultati apparentemente incoerenti è stato quando avevo due righe di codice che guardano allo come si riferiscono allo stesso tipo, ma che hanno effettivamente caricato quel tipo da diversi classloader.

+0

Accidenti, non lo faccio _questo. La stranezza sta spuntando quando si esegue un semplice caso di test di junit. Questo mi dà abbastanza informazioni per supporre che ho fatto qualcosa di stupido e ho solo bisogno di semplificare. Grazie. – morgancodes

-1

Ci si potrebbe volere "isAssignable" invece di instanceof:

if (MyInterface.isAssignableFrom(myObject.getClass())) { 
    // do work here 
} 

Ciò restituirà vero per le classi che implementano l'interfaccia.

+0

Così fa instanceof. –

+0

Esattamente uguale a instanceof, ma genera un NPE se myObject è nullo. – cadrian

+0

... meglio usare MyInterface.class.isInstance (myObject) - questo non getta un NPE. Anche questo è inutile se si conosce MyInterface in fase di compilazione - potrebbe anche usare l'istanza di –

9

instanceof restituisce sempre false per null. Non viene compilato se sarebbe impossibile che il tipo statico a sinistra non sia un'istanza del tipo specificato. Oltre a questo, dovrebbe funzionare senza sorpresa.

A differenza di C++ (e credo Smalltalk), un oggetto non può cambiare tipo in fase di esecuzione. In C++ il tipo cambia durante la costruzione, in modo tale che i metodi non possano essere chiamati da un costruttore ai metodi della classe derivata [sottoclasse].

3

Finché non si verificano problemi di caricamento classi, instanceof funziona in modo coerente. Immagino tu sappia Un'istanza di B restituisce true se A è ereditata da B, o alcune delle interfacce A implementa o le classi A si estende, sono l'istanza di B.

Se si ottiene un falso quando ci si aspetta vero, probabilmente lo si cercando di confrontare le istanze provenienti da diversi ClassLoaders.

9

Ok, problema risolto. Come al solito, il problema era meno strano di quanto pensassi. Il progetto a cui sto lavorando si trova nella sfortunata condizione di avere nomi di classi duplicati. Stavo creando la classe usando foo.MyInterface e testando per esempio bar.MyInterface. Grazie per le risposte. Mi ha davvero aiutato a pensarci.

+3

Ironia della sorte, ho quasi incluso questa possibilità nella mia risposta, ma per qualche motivo non è stato alla fine. Questo mi insegnerà - la prossima volta pubblicherò tutte le idee, non importa quanto stupide :) –

+0

Grazie per aver risposto alla tua stessa domanda, è stato anche il mio stupido errore! –

Problemi correlati