web-dev-qa-db-fra.com

Tester si l'objet est une instance d'un type de paramètre

Existe-t-il un moyen de déterminer si un objet est une instance de type générique?

public <T> test(Object obj) {
    if (obj instanceof T) {
        ...
    }
}

Cela ne fonctionne clairement pas. Y a-t-il une alternative? Comme je veux utiliser Java réflexion pour instancier une classe, puis vérifiez qu'elle est de type générique T.

70
Nikordaris

La seule façon de faire cette vérification est de disposer de l'objet Class représentant le type:

Class<T> type; //maybe passed into the method
if ( type.isInstance(obj) ) {
   //...
}
111
Mark Peters

Pour étendre l'échantillon de Mark Peters, vous voulez souvent faire quelque chose comme:

Class<T> type; //maybe passed to the method
if ( type.isInstance(obj) ) {
   T t = type.cast(obj);
   // ...
}
18
Puce

Vous pouvez essayer ça,

// Cast your object to the generic type.
T data = null;
try {
    data = (T) obj;
} catch (ClassCastException cce) {
    // Log the error.
}

// Check if the cast completed successfully.
if(data != null) {
    // whatever....
}
5

Si vous ne voulez pas passer le type de classe comme paramètre comme mentionné par Mark Peters, vous pouvez utiliser le code suivant. Félicitations à David O'Meara.

  Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                  .getActualTypeArguments()[0];
  if (type.isInstance(obj)) {
      ...
  }
5
Ton Snoei

Il serait plus judicieux de mettre la restriction sur l'endroit où le type T est utilisé pour paramétrer le type Class. Lorsque vous passez le type, au lieu d'utiliser quelque chose comme Class<?>, Tu devrais utiliser Class<? extends T>.

3
Chris Dennett

Cela ne fonctionnera (en partie) que si vous avez un objet de type T. Ensuite, vous pouvez obtenir la classe de cet objet, voir Java.lang.Class<T> et trouver si c'est la même chose que l'objet en question.

Mais notez que cela va à l'encontre de la raison même pour laquelle nous avons des statistiques: l'utilisation d'un type générique est une façon de dire que vous ne vous souciez pas de quel type il s'agit réellement (jusqu'aux limites supérieures et inférieures qui peuvent être spécifiées).

1
Ingo

Cela fonctionne aussi

public <T> void functionName(T input){
    Foo foo = new Foo(); // one of the expected objects
    if(input.getClass().isInstance(foo){
       doSomeThingWith((Foo)input);
    }
}

Démo complète Démo en direct sur repl.it

0
blongho