2010-11-10 6 views
23

La chose générique entière me fait un peu tourner en boucle, et plus encore le RTT.Java isInstance vs opérateur instanceOf

Spécifique? Eh bien, voici l'essentiel:

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

puis je l'appellerais comme ceci:

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

Il en est ainsi que je peux vraiment affecter de manière flexible le type de retour de la requête dans l'aide réelle. Il fait du casting et de la création d'objets. Ce que je vois, c'est qu'il n'y a pas de correspondance, est-ce que je devrais faire autrement? Ou l'idée est-elle simplement mauvaise?

Et le vrai cœur de ceci est que je ne comprends pas la différence entre class.isInstance et l'opérateur instanceOf? Devrais-je utiliser ce dernier?

Répondre

29

Cette est ainsi que je peux vraiment assigner de manière flexible le type de retour de la requête dans l'assistant réel.

Il n'y a rien souple sur le type de retour de cette méthode

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

Il renvoie toujours une instance de QueryHelper. Si vous voulez que le type de retour à être flexible, vous devrez définir quelque chose comme:

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

Maintenant, le type de retour est flexible, car elle dépendra du type de l'argument

Et le vrai cœur de ceci est que je ne comprends pas la différence entre class.isInstance et l'opérateur instanceOf?

La différence est que instanceof-t un type chèque qui est fixé à la compilation, par exemple:

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

toujours vérifier que myVar est une instance de Foo, alors que

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

va vérifier que myVar est une instance de expectedType, mais expectedType peut être de type différent chaque fois que la méthode est appelée

+0

Votre utilisation ex ample pour isInstance est en arrière. Serait expectedType.isInstance (myVar); – Affe

+0

Merci de préciser que - j'ai dû ralentir et penser quand j'écrivais ce code. Il a depuis changé de forme, pour être réellement utile. Merci encore! – rybit

1

L'argument attendu de isInstance est un objet qui peut être une instance de la classe représentée par votre objet de classe. Ce que vous comparez est une instance de la classe ... java.lang.Class! Donc ça ne va pas correspondre.

par exemple, serait vrai:

Class.class.isInstance(SomeRelatedClass.class); 

serait également vrai (sans commentaire d'architecture sur la santé mentale de la construction réellement votre aide de la requête de cette façon)

expectedReturn.isInstance(new SomeRelatedClass()); 
3

Class.isInstance() doesn Ne travaillez pas comme votre code l'attend. Il teste si l'objet que vous lui passez est une instance de la classe. Dans votre code:

expectedReturn.isInstance(SomeRelatedClass.class) 

L'objet que vous transmettez est un objet Class. Essayez plutôt, qui retourne vrai:

Class.class.isInstance(SomeRelatedClass.class); 

Qu'est-ce que vous cherchez probablement est Class.isAssignableFrom(), par exemple:

Object.class.isAssignableFrom(Class.class); 

signifie que vous pouvez faire ceci:

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