Java isInstance vs instanceOf operator

le truc des génériques me fait un peu peur, et plus encore le RTT.

Specificis? Voici l'essentiel:

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

et puis je l'appellerais comme ça:

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

c'est pour que je puisse affecter de manière vraiment flexible le type de retour de requête dans le helper actuel. Il fait du casting et de la création d'objet. Ce que je vois c'est qu'il n'y a pas de match, dois-je le faire d'une autre façon? Ou est l'idée tout simplement mauvais?

et le vrai cœur de ceci est que je ne comprends pas la différence entre la classe.isInstance et l'opérateur instanceOf? Dois-je utiliser celui-ci?

24

3 réponses

c'est pour que je puisse affecter de manière vraiment flexible le type de retour de requête dans le helper actuel.

il n'y a rien de flexible dans 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 retournera toujours une instance de QueryHelper . Si vous voulez que le type de retour soit flexible, vous devez le Définir comme quelque chose comme:

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

maintenant le type de retour est flexible, parce qu'il va dépendent du type de l'argument

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

la différence est que instanceof effectue un contrôle de type qui est fixé au moment de la compilation, par exemple:

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

vérifiera toujours que myVar est une instance de Foo, tandis que

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

vérifiera que myVar est une instance d'expectdtype, mais expectdtype peut être un type différent chaque fois que la méthode est appelée

29
répondu Dónal 2014-04-03 08:57:43

de la Classe.isInstance () ne fonctionne pas comme votre code l'attend. Il teste si l'objet que vous transmettez est une instance de la classe. En code you:

expectedReturn.isInstance(SomeRelatedClass.class)

l'objet que vous passez est un objet de classe. Essayez ceci à la place, qui retourne true:

Class.class.isInstance(SomeRelatedClass.class);

ce que vous cherchez probablement, c'est la classe .isassignable from () , e.g.:

Object.class.isAssignableFrom(Class.class);

signifie que vous pouvez le faire:

Class klass = ...;
Object o = klass;
3
répondu vanza 2010-11-10 00:26:49

l'argument attendu d'isInstance est un objet qui peut être une Instance de la classe que votre objet de classe représente. Ce à quoi vous le comparez est une instance de la classe... java.lang.Class ! Donc ça ne va pas correspondre.

par exemple, qui serait le vrai:

Class.class.isInstance(SomeRelatedClass.class);

serait également vrai (sans commentaire architectural sur la santé mentale de réellement construire votre assistant de requête de cette façon)

expectedReturn.isInstance(new SomeRelatedClass());
1
répondu Affe 2010-11-10 00:26:47