Come vedere se un oggetto è un array senza usare la riflessione?


99

Come posso vedere in Java se un oggetto è un array senza usare la riflessione? E come posso scorrere tutti gli elementi senza utilizzare la riflessione?

Uso Google GWT quindi non sono autorizzato a utilizzare la riflessione :(

Mi piacerebbe implementare i seguenti metodi senza utilizzare la selezione:

private boolean isArray(final Object obj) {
  //??..
}

private String toString(final Object arrayObject) {
  //??..
}

BTW: nemmeno voglio usare JavaScript in modo da poterlo usare in ambienti non GWT.

Risposte:


248

Puoi usare Class.isArray()

public static boolean isArray(Object obj)
{
    return obj!=null && obj.getClass().isArray();
}

Funziona sia per gli array di oggetti che per quelli di tipo primitivo.

Per toString dai un'occhiata a Arrays.toString. Dovrai controllare il tipo di array e chiamare il toStringmetodo appropriato .


1
Vale la pena aggiungere che puoi scoprire il tipo di array usando obj.getClass().getComponentType().
— Steve Chambers

68

Puoi usare instanceof.

JLS 15.20.2 Operatore di confronto dei tipi instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

In fase di esecuzione, il risultato instanceofdell'operatore è truese il valore di RelationalExpression non è nulle il riferimento potrebbe essere sottoposto a cast a ReferenceType senza sollevare a ClassCastException. Altrimenti il ​​risultato è false.

Ciò significa che puoi fare qualcosa del genere:

Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"        

Dovreste controllare se l'oggetto è un instanceof boolean[], byte[], short[], char[], int[], long[], float[], double[], o Object[], se si vuole rilevare tutti i tipi di array.

Inoltre, an int[][]è an instanceof Object[], quindi a seconda di come si desidera gestire gli array annidati, può diventare complicato.

Per il toString, java.util.Arraysha a toString(int[])e altri sovraccarichi che puoi usare. Ha anche deepToString(Object[])per gli array annidati.

public String toString(Object arr) {
   if (arr instanceof int[]) {
      return Arrays.toString((int[]) arr);
   } else //...
}

Sarà molto ripetitivo (ma anche java.util.Arraysmolto ripetitivo ), ma è così in Java con gli array.

Guarda anche


Grazie, non si è reso conto che è così semplice. Il pensiero insstanceof non può essere usato direttamente con T [] :(
— edbras

2
BTW: ho anche notato un altro bel modo per scoprire se qualcosa è un array Class.isArray () (usato in Arrays.deepToString ()).
— edbras

@edbras: sì, è quello che diceva Steve Kuo in basso. La mia soluzione utilizza un costrutto linguistico puro invece della chiamata API.
— lubrificanti poligenici

Funziona bene, solo non uso instanceof ma getClass come confronto. Qualcosa come: if (array.getClass == int []. Class) {Arrays.toString ((int []) array); } Grazie a tutti ..
— edbras

@edbras: Ecco come java.util.Arraysfunziona, sì. Vedo che hai letto il codice a cui mi sono collegato.
— lubrificanti poligenici

35

È possibile accedere separatamente a ciascun elemento di un array utilizzando il codice seguente:

Object o=...;
if ( o.getClass().isArray() ) {
    for(int i=0; i<Array.getLength(o); i++){
        System.out.println(Array.get(o, i));
    }
}

Si noti che non è necessario sapere che tipo di array sottostante è, poiché funzionerà per qualsiasi array.


2
isArray()era già adeguatamente trattato nelle risposte pubblicate 4 anni prima di questa.
— Jason C

15
Questa risposta è ottima perché ci mostra come ottenere la dimensione di un array e recuperare un elemento senza conoscere il suo tipo di contenuto. Sono sicuro che la maggior parte delle persone non ha mai scritto un codice come questo prima.
— Christopher Yang

@MaartenBodewes - Vorrei utilizzare questo collegamento per decidere cosa significa "non usare la riflessione" per GWT.
— Stephen C

10

Non esiste alcuna relazione di sottotipizzazione tra array di tipo primitivo o tra un array di un tipo primitivo e un array di un tipo di riferimento. Vedere JLS 4.10.3 .

Pertanto, quanto segue non è corretto come test per vedere se objè un array di qualsiasi tipo :

// INCORRECT!
public boolean isArray(final Object obj) {
    return obj instanceof Object[];
}

In particolare, non funziona se objè un array 1-D di primitive. (Funziona per array primitivi con dimensioni maggiori, perché tutti i tipi di array sono sottotipi di Object. Ma in questo caso è discutibile.)

Uso Google GWT quindi non sono autorizzato a utilizzare la riflessione :(

La soluzione migliore (per la isArrayparte di matrice della domanda) dipende da ciò che conta come "usare la riflessione".

  • In GWT, la chiamata obj.getClass().isArray()non conta come utilizzare la riflessione 1 , quindi questa è la soluzione migliore.

  • Altrimenti, il modo migliore per capire se un oggetto ha un tipo di matrice è usare una sequenza di instanceofespressioni.

    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[];
    }
  • Potresti anche provare a scherzare con il nome della classe dell'oggetto come segue, ma la chiamata a obj.getClass()rasenta la riflessione.

    public boolean isArray(final Object obj) {
        return obj.getClass().toString().charAt(0) == '[';
    }

1 - Più precisamente, il Class.isArraymetodo è elencato come supportato da GWT in questa pagina .


0

È possibile creare una classe di utilità per verificare se la classe rappresenta una raccolta , una mappa o una matrice

  public static boolean isCollection(Class<?> rawPropertyType) {
        return Collection.class.isAssignableFrom(rawPropertyType) || 
               Map.class.isAssignableFrom(rawPropertyType) || 
               rawPropertyType.isArray();
 }

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.