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[]) {}
?
Dans la plupart des cas, vous devez utiliser l’opérateur instanceof
pour tester si un object est un tableau.
Généralement, vous testez le type d’un object avant de le réduire à un type particulier connu à la compilation. Par exemple, vous avez peut-être écrit du code qui peut fonctionner avec un Integer[]
ou un int[]
. Vous voulez garder vos moulages 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
traduit par un code d’octet “instanceof” spécifique, optimisé dans la plupart des implémentations JVM.
Dans de rares cas, vous pouvez utiliser la reflection pour parcourir un graphe d’objects de types inconnus. Dans de tels cas, la méthode isArray()
peut être utile car vous ne connaissez pas le type de composant au moment de la compilation. Vous pouvez, par exemple, implémenter une sorte de mécanisme de sérialisation et pouvoir transmettre chaque composant de la baie à la même méthode de sérialisation, quel que soit son type.
Il existe deux cas particuliers: les références null et les références aux tableaux primitifs.
Une référence null entraînera une isArray
de résultat d’ instanceof
, tandis que isArray
lève une isArray
NullPointerException
.
Appliquée à un tableau primitif, l’ instanceof
renvoie false
sauf si le type de composant de l’opérande droit correspond exactement au type de composant. En revanche, isArray()
renvoie true
pour tout type de composant.
Dans ce dernier cas, si obj est nul, vous n’obtiendrez pas une exception NullPointerException, mais un false.
Si obj
est de type int[]
, alors cela aura un tableau Class
mais ne sera pas une instance de Object[]
. Alors qu’est-ce que tu veux faire avec obj
. Si vous voulez le lancer, allez avec instanceof
. Si vous allez utiliser la reflection, utilisez alors .getClass().isArray()
.
getClass().isArray()
est nettement plus lent sous Sun Java 5 ou JRE que sous IBM.
Tant que l’utilisation de clazz.getName().charAt(0) == '['
est plus rapide sur Sun JVM.
J’ai récemment rencontré un problème lors de la mise à niveau d’une application Groovy de JDK 5 vers JDK 6. L’utilisation de isArray()
échoué dans JDK6:
MissingMethodException: No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...
Passer à instanceof Object[]
résolu ce problème.
La reflection Java est pour les cas où vous ne disposez pas d’une instance de la classe disponible pour faire “instanceof”. Par exemple, si vous écrivez une sorte de structure d’injection qui injecte des valeurs dans une nouvelle instance d’une classe, comme 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/
Si 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 objects de classe). Ce n’est pas que ce soit “Wrong” ou quoi que ce soit, mais tout ce qui concerne la reflection est généralement moins évident et moins clair.
Il n’y a pas de différence de comportement que je puisse trouver entre les deux (autre que le cas évident évident). En ce qui concerne la version à préférer, j’irais avec la seconde. C’est la manière standard de le faire en Java.
Si cela perturbe les lecteurs de votre code (parce que Ssortingng[] instanceof Object[]
est vrai), vous pouvez utiliser le premier pour être plus explicite si les réviseurs de code continuent à le demander.