Java de la matrice de réflexion: isArray vs instanceof
Est-il une préférence ou une différence de comportement entre l'utilisation
if(obj.getClass().isArray()) {}
et
if(obj instanceof Object[]) {}
?
Vous devez vous connecter pour publier un commentaire.
Dans la plupart des cas, vous devez utiliser le
instanceof
opérateur pour tester si un objet est un tableau.Généralement, vous tester un type de l'objet avant de passer à un type particulier qui est connu au moment de la compilation. Par exemple, peut-être que vous avez écrit du code qui peut travailler avec un
Integer[]
ou unint[]
. Vous voulez protéger vos moulages avecinstanceof
:Au niveau de la JVM, le
instanceof
opérateur se traduit par un spécifique "instanceof" du byte-code, qui est optimisé dans la plupart des JVM implémentations.Dans de plus rares cas, vous pourriez être en utilisant la réflexion parcourir un graphe d'objets de types inconnus. Dans de tels cas, le
isArray()
méthode peut être utile parce que vous ne connaissez pas le type de composant au moment de la compilation; vous pourriez, par exemple, être mise en œuvre une sorte de mécanisme de sérialisation et d'être en mesure de passer à chaque élément du tableau à la même méthode de sérialisation, indépendamment de leur type.Il y a deux cas particuliers: null références et des références à des tableaux primitifs.
Une référence null sera la cause de
instanceof
de résultatfalse
, tandis que leisArray
jette unNullPointerException
.Appliquée à une primitive de la baie, le
instanceof
rendementsfalse
à moins que le type de composant sur la partie droite de l'opérande correspond exactement au type de composant. En revanche,isArray()
sera de retourtrue
pour n'importe quel type de composant.instanceof
de ne pas travailler avec des tableaux de types intégraux.obj instanceof int[]
rendementsfalse
lorsque vous affectez uneint[]
àobj
, vous vous trompez.obj instanceof Object[]
rendementsfalse
siObject obj = new int[7]
.java.lang.Object
, ce qui fait du sens. Maisinstanceof
peut toujours être utilisé pour tester la primitive tableaux.isArray()
doit être utilisé. Dans la très non cas particulier de n'avoir que des tableaux d'objets,instanceof
fournit une alternative haute performance.instanceof
(une vérification approfondie, y compris les types primitifs) est plus rapide et ainsi de mieux que deisArray()
Object[]
. La manutention de tout type de tableau est un cas spécial, extrêmement rares par rapport à l'essai pour un type particulier. Les essais d'un type particulier est fait avecinstanceof
, pas avec une méthode spéciale. Voulez-vous pourisString()
,isInputStream()
,isConnection()
,isInteger()
, à l'infini les méthodes de chaque classe?<-- -->
commentaire. Si vous éditer le post pour y inclure des explications plus claires sur les avantages de chaque méthode (peut-être en retrait de la<--
et-->
), je vais changer ma -1 à +1.Dans ce dernier cas, si obj est nul, vous n'obtiendrez pas une exception NullPointerException mais un faux.
Si
obj
est de typeint[]
dire, alors qui va avoir un tableauClass
mais ne pas être une instance deObject[]
. Alors, que voulez-vous faire avecobj
. Si vous vous apprêtez à lancer, aller avecinstanceof
. Si vous allez utiliser la réflexion, puis utilisez.getClass().isArray()
.J'ai récemment rencontré un problème de mise à niveau d'un Groovy application de JDK JDK 5 à 6. À l'aide de
isArray()
échoué dans JDK6:Changer de
instanceof Object[]
corrigé cela.isArray
est une méthode deClass
, pasType
, alors, évidemment,GenericArrayTypeImpl
n'ont pas cette méthode. EtgetClass
ne pourra jamais retourner un non-Class
Type
, de sorte que vous (ou Groovy??) doit avoir fait quelque chose de mal à cela, comme en supposant que tous lesType
est unClass
.getClass().isArray()
est significativement plus lente sur Sun Java 5 ou 6 JRE que sur IBM.Autant que l'utilisation de
clazz.getName().charAt(0) == '['
est plus rapide sur la JVM de Sun.Java tableau reflet est pour les cas où vous n'avez pas une instance de la Classe disponibles pour le faire "instanceof" sur. Par exemple, si vous écrivez une sorte de framework injection, qui injecte des valeurs dans une nouvelle instance d'une classe, comme la JPA est le cas, vous devez utiliser le isArray() fonctionnalité.
J'ai blogué à propos de ce début de décembre.
http://blog.adamsbros.org/2010/12/08/java-array-reflection/
Si jamais vous avez le choix entre une réflexion et une solution et un non-réfléchissant solution, ne prenez jamais l'réfléchissant un (impliquant des objets de la Classe). C'est pas que c'est "Mal" ou quoi que ce soit, mais en ce qui concerne la réflexion est généralement moins évident et moins claire.
Il n'y a pas de différence dans le comportement que j'ai pu trouver entre les deux (autres que des évidences, null cas). Comme pour la version à préférer, j'irais avec le deuxième. C'est la façon standard de le faire en Java.
Si on confond les lecteurs de votre code (parce que
String[] instanceof Object[]
est vrai), vous pouvez utiliser le premier à être plus explicite si le code réviseurs d'insister à ce sujet.