web-dev-qa-db-fra.com

Java isInstance vs instanceOf, opérateur

Le truc générique me lance un peu pour une boucle, et plus encore le RTT.

Specificis? Ah 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;
  }
}

et je l'appellerais ainsi:

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

C'est pour que je puisse vraiment attribuer de manière flexible le type de retour de 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, dois-je le faire d'une autre manière? 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? Dois-je utiliser ce dernier?

25
rybit

C'est pour que je puisse vraiment attribuer de manière flexible le type de retour de requête dans l'aide réelle.

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, car il 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 effectue une vérification de type qui est fixée 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, alors que

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

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

30
Dónal

Class.isInstance () ne fonctionne pas comme le prévoit votre code. 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 passez est un objet Class. Essayez ceci à la place, qui retourne vrai:

Class.class.isInstance(SomeRelatedClass.class);

Ce que vous recherchez probablement est Class.isAssignableFrom () , par exemple:

Object.class.isAssignableFrom(Class.class);

Signifie que vous pouvez le faire:

Class klass = ...;
Object o = klass;
3
vanza

L'argument attendu de 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, serait vrai:

Class.class.isInstance(SomeRelatedClass.class);

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

expectedReturn.isInstance(new SomeRelatedClass());
1
Affe