web-dev-qa-db-fra.com

Comment voir si un objet est un tableau sans utiliser de réflexion?

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.

79
edbras

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.

212
Steve Kuo

Vous pouvez utiliser instanceof.

JLS 15.20.2 Opérateur de comparaison de types instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

Au moment de l'exécution, le résultat de l'opérateur instanceof est true si la valeur de RelationalExpression n'est pas null et que la référence peut être convertie en ReferenceType sans générer de ClassCastException. Sinon, le résultat est false.

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.

Voir également

62
polygenelubricants

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.

28
user1928596

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 .

9
Stephen C

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();
 }
0
Lucas Pires