Réflexion de tableau Java: isArray vs instanceof

Y a-t-il une différence de préférence ou de comportement entre l'utilisation de:

if(obj.getClass().isArray()) {}

Et

if(obj instanceof Object[]) {}

?

162
demandé sur David Citron 2008-10-21 00:56:36

8 réponses

Dans la plupart des cas, vous devez utiliser l'opérateur instanceof pour tester si un objet est un tableau.

Généralement, vous testez le type d'un objet avant de passer à un type particulier connu au moment de la compilation. Par exemple, peut-être avez-vous écrit du code qui peut fonctionner avec un Integer[] ou un int[]. Vous voulez garder vos lancers avec instanceof:

if (obj instanceof Integer[]) {
    Integer[] array = (Integer[]) obj;
    /* Use the boxed array */
} else if (obj instanceof int[]) {
    int[] array = (int[]) obj;
    /* Use the primitive array */
} else ...

Au niveau de la JVM, l'opérateur instanceof se traduit par un code d'octet "instanceof" spécifique, qui est optimisé dans la plupart des JVM application.

Dans des cas plus rares, vous pouvez utiliser la réflexion pour parcourir un graphe d'objet de types inconnus. Dans des cas comme celui-ci, la méthode isArray() peut être utile car vous ne connaissez pas le type de composant au moment de la compilation; vous pourriez, par exemple, implémenter une sorte de mécanisme de sérialisation et être capable de passer chaque composant du tableau à la même méthode de sérialisation, quel que soit le type.

Il y a deux cas particuliers: références nulles et références à primitive tableau.

Une référence null entraînera instanceof À résultat false, tandis que le isArray jette un NullPointerException.

Appliqué à un tableau primitif, le instanceof donne false sauf si le type de composant de l'opérande de droite correspond exactement au type de Composant. En revanche, {[6] } renvoie true pour tout type de Composant.

191
répondu erickson 2018-02-20 00:37:04

Dans ce dernier cas, si obj est null, vous n'obtiendrez pas une NullPointerException mais un false.

31
répondu Burkhard 2009-08-27 15:28:00

Si {[0] } est de type int[] disons, alors cela aura un tableau Class mais ne sera pas une instance de Object[]. Alors, que voulez-vous faire avec obj. Si vous allez le lancer, allez avec instanceof. Si vous allez utiliser la réflexion, utilisez .getClass().isArray().

8
répondu Tom Hawtin - tackline 2008-10-21 12:16:05

J'ai récemment rencontré un problème de mise à niveau D'une application Groovy de JDK 5 à JDK 6. L'utilisation de isArray() a échoué dans JDK6:

MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...

Changer en instanceof Object[] Correction de cela.

5
répondu dturanski 2012-10-13 13:44:14

getClass().isArray() est significativement plus lent sur Sun Java 5 ou 6 JRE que sur IBM.

Tellement que l'utilisation de clazz.getName().charAt(0) == '[' est plus rapide sur la JVM Sun.

4
répondu Sebastien Tardif 2011-11-09 19:15:20

La réflexion de tableau Java est pour les cas où vous n'avez pas une instance de la classe disponible pour faire "instanceof"sur. Par exemple, si vous écrivez une sorte de framework d'injection, qui injecte des valeurs dans une nouvelle instance d'une classe, comme le fait JPA, vous devez utiliser la fonctionnalité isArray ().

J'ai blogué à ce sujet plus tôt en décembre. http://blog.adamsbros.org/2010/12/08/java-array-reflection/

3
répondu Trenton D. Adams 2011-01-01 01:46:26

Si jamais vous avez le choix entre une solution réfléchissante et une solution non réfléchissante, ne choisissez jamais la solution réfléchissante (impliquant des objets de classe). Ce n'est pas que ce soit "faux" ou quoi que ce soit, mais tout ce qui implique la réflexion est généralement moins évident et moins clair.

2
répondu Bill K 2008-10-20 21:06:06

Il n'y a pas de différence de comportement que je peux trouver entre les deux (autre que le cas null évident). Quant à la version à préférer, j'irais avec la seconde. C'est la façon standard de le faire en Java.

Si cela confond les lecteurs de votre code (parce que String[] instanceof Object[] est vrai), vous pouvez utiliser le premier pour être plus explicite si les réviseurs de code continuent à poser des questions à ce sujet.

0
répondu hazzen 2008-10-20 21:02:27