2010-11-10 15 views
23

L'intera cosa generica è un po 'come lanciarmi per un ciclo, e più ancora l'RTT.Java isInstance vs instanceOf operator

Specificis? Ah bene ecco il succo del discorso:

enum QueryHelper { 
    query1, 
    query2; 
    static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) { 
    if (expectedReturn.isInstance (SomeRelatedClass.class)) 
     return query1; 
    else 
     return query2; 
    } 
} 

e quindi vorrei chiamarlo in questo modo:

... 
QueryHelper helper = QueryHelper.getQueryHelper(SomeRelatedClass.class); 
... 

Questo è così che posso davvero flessibile assegnare il tipo di ritorno query nel aiutante reale. Fa un po 'di casting e creazione di oggetti. Quello che sto vedendo è che non c'è corrispondenza, dovrei farlo in qualche altro modo? O l'intera idea è solo brutta?

E il vero cuore di questo è che non capisco la differenza tra class.isInstance e l'operatore instanceOf? Dovrei usare quest'ultimo?

risposta

29

Questo è così che posso assegnare in modo flessibile il tipo di ritorno della query nell'help attuale.

Nulla flessibile circa il tipo di ritorno di questo metodo

static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) { 
    if (expectedReturn.isInstance (SomeRelatedClass.class)) 
     return query1; 
    else 
     return query2; 
} 

Esso sempre restituirà un'istanza di QueryHelper. Se si desidera che il tipo di ritorno di essere flessibili si avrebbe bisogno di definirla come qualcosa di simile:

static <T> T getQueryHelper (Class<T> expectedReturn) { 
} 

Ora il tipo di ritorno è flessibile, perché dipende dal tipo dell'argomento

E il vero cuore di questo è che non capisco la differenza tra class.isInstance e l'operatore instanceOf?

La differenza è che instanceof fa un tipo controllare che è fissato al momento della compilazione, ad esempio:

static boolean isInstance(Object myVar) { 
    return (myVar instanceof Foo); 
} 

sempre controllare che myVar è un'istanza di Foo, mentre

static <T> boolean isInstance(Object myVar, Class<T> expectedType) { 
    return expectedType.isInstance(myVar); 
} 

verificherà che myVar sia un'istanza di expectedType, ma expectedType può essere di un tipo diverso ogni volta che viene chiamato il metodo

+0

Il tuo utilizzo ex ampio per isInstance è indietro. Sarebbe previstoType.isInstance (myVar); – Affe

+0

Grazie per aver chiarito che - ho bisogno di rallentare e pensare quando stavo scrivendo questo codice. Da allora ha cambiato forma, per essere effettivamente utile. Grazie ancora! – rybit

1

L'argomento previsto di isInstance è un oggetto che può essere un'istanza della classe rappresentata dall'oggetto di classe. Quello a cui stai confrontando è un'istanza della classe ... java.lang.Class! Quindi non combacia.

ad esempio, sarebbe vero:

Class.class.isInstance(SomeRelatedClass.class); 

Inoltre sarebbe vero (senza commento architettonico sulla sanità mentale della realtà costruire query aiutante in questo modo)

expectedReturn.isInstance(new SomeRelatedClass()); 
3

Class.isInstance() doesn Funziona come previsto dal tuo codice. Verifica se l'oggetto che gli passi è un'istanza della classe. Nel tuo codice:

expectedReturn.isInstance(SomeRelatedClass.class) 

L'oggetto che stai passando è un oggetto di classe. Prova a modificare, che restituisce vero:

Class.class.isInstance(SomeRelatedClass.class); 

Quello che probabilmente stai cercando è Class.isAssignableFrom(), ad esempio:

Object.class.isAssignableFrom(Class.class); 

significa che si può fare questo:

Class klass = ...; 
Object o = klass;