Comment voir en Java si un objet est un tableau sans utiliser de réflexion? Et comment puis-je parcourir tous les éléments sans utiliser de réflexion?
J'utilise Google GWT, je ne suis donc pas autorisé à utiliser le mode réflexion :(
J'adorerais implémenter les méthodes suivantes sans utiliser refelection:
private boolean isArray(final Object obj) {
//??..
}
private String toString(final Object arrayObject) {
//??..
}
BTW: je ne veux pas non plus utiliser JavaScript pour pouvoir l'utiliser dans des environnements autres que GWT.
Vous pouvez utiliser Class.isArray()
public static boolean isArray(Object obj)
{
return obj!=null && obj.getClass().isArray();
}
Cela fonctionne à la fois pour les tableaux de type objet et primitif.
Pour toString, regardez Arrays.toString
. Vous devrez vérifier le type de tableau et appeler la méthode toString
appropriée.
Vous pouvez utiliser instanceof
.
instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
Au moment de l'exécution, le résultat de l'opérateur
instanceof
esttrue
si la valeur de RelationalExpression n'est pasnull
et que la référence peut être convertie en ReferenceType sans générer deClassCastException
. Sinon, le résultat estfalse
.
Cela signifie que vous pouvez faire quelque chose comme ceci:
Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"
Vous devez vérifier si l'objet est un instanceof boolean[]
, byte[]
, short[]
, char[]
, int[]
, long[]
, float[]
, double[]
, ou Object[]
, si vous souhaitez détecter tous les types de tableau.
En outre, un int[][]
est un instanceof Object[]
; ainsi, selon la manière dont vous voulez gérer les tableaux imbriqués, cela peut devenir compliqué.
Pour la toString
, Java.util.Arrays
a une toString(int[])
et d’autres surcharges que vous pouvez utiliser. Il a également deepToString(Object[])
pour les tableaux imbriqués.
public String toString(Object arr) {
if (arr instanceof int[]) {
return Arrays.toString((int[]) arr);
} else //...
}
Cela va être très répétitif (mais même Java.util.Arrays
est très répétitif ), mais c'est comme ça en Java avec des tableaux.
On peut accéder à chaque élément d'un tableau séparément en utilisant le code suivant:
Object o=...;
if ( o.getClass().isArray() ) {
for(int i=0; i<Array.getLength(o); i++){
System.out.println(Array.get(o, i));
}
}
Notez qu'il est inutile de savoir de quel type de tableau il s'agit, cela fonctionnera pour n'importe quel tableau.
Il n'y a pas de relation de sous-typage entre des tableaux de type primitif ou entre un tableau de type primitif et un tableau de type référence. Voir JLS 4.10.3 .
Par conséquent, ce qui suit est incorrect en tant que test pour voir si obj
est un tableau de tout type:
// INCORRECT!
public boolean isArray(final Object obj) {
return obj instanceof Object[];
}
En particulier, cela ne fonctionne pas si obj
est un tableau de primitives 1-D. (Cela fonctionne cependant pour les tableaux primitifs avec des dimensions plus élevées, car tous les types de tableaux sont des sous-types de Object
. Mais c'est sans objet dans ce cas.)
J'utilise Google GWT, je ne suis donc pas autorisé à utiliser le mode réflexion :(
La meilleure solution (à la partie de la question contenant le tableau isArray
) dépend de ce qui compte comme "utilisation de la réflexion".
Dans GWT, l'appel de obj.getClass().isArray()
ne compte pas comme utilisant la réflexion1, c’est la meilleure solution.
Sinon, le meilleur moyen de déterminer si un objet a un type de tableau est d'utiliser une séquence d'expressions instanceof
.
public boolean isArray(final Object obj) {
return obj instanceof Object[] || obj instanceof boolean[] ||
obj instanceof byte[] || obj instanceof short[] ||
obj instanceof char[] || obj instanceof int[] ||
obj instanceof long[] || obj instanceof float[] ||
obj instanceof double[];
}
Vous pouvez également essayer de jouer avec le nom de la classe de l'objet comme suit, mais l'appel à obj.getClass()
est proche de la réflexion.
public boolean isArray(final Object obj) {
return obj.getClass().toString().charAt(0) == '[';
}
1 - Plus précisément, la méthode Class.isArray
est listée comme supportée par GWT dans cette page .
Vous pouvez créer une classe d’utilitaires pour vérifier si elle représente Collection, Map ou Array.
public static boolean isCollection(Class<?> rawPropertyType) {
return Collection.class.isAssignableFrom(rawPropertyType) ||
Map.class.isAssignableFrom(rawPropertyType) ||
rawPropertyType.isArray();
}