webentwicklung-frage-antwort-db.com.de

Wie kann man sehen, ob ein Objekt ein Array ist, ohne Reflektion zu verwenden?

Wie kann ich in Java sehen, ob ein Objekt ein Array ohne Reflektion ist? Wie kann ich alle Elemente ohne Reflektion durchlaufen?

Ich benutze Google GWT, also darf ich Reflection nicht verwenden :(

Ich würde gerne die folgenden Methoden ohne Refelection implementieren:

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

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

Übrigens: Ich möchte auch kein JavaScript verwenden, damit ich es in Nicht-GWT-Umgebungen verwenden kann.

79
edbras

Sie können Class.isArray() verwenden.

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

Dies funktioniert sowohl für Objektarrays als auch für primitive Arrays.

Für toString werfen Sie einen Blick auf Arrays.toString. Sie müssen den Array-Typ überprüfen und die entsprechende toString-Methode aufrufen.

212
Steve Kuo

Sie können instanceof verwenden.

JLS 15.20.2 Typvergleichsoperator instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

Zur Laufzeit ist das Ergebnis des instanceof-Operators true, wenn der Wert von RelationalExpression nicht null ist und der Verweis in ReferenceType umgewandelt werden könnte, ohne eine ClassCastException zu erzeugen. Ansonsten ist das Ergebnis false.

Das bedeutet, dass Sie so etwas tun können:

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

Sie müssen überprüfen, ob es sich bei dem Objekt um einen instanceof boolean[], byte[], short[], char[], int[], long[], float[], double[] oder Object[] handelt, wenn Sie alle Arraytypen ermitteln möchten.

Ein int[][] ist auch ein instanceof Object[]. Abhängig davon, wie Sie mit verschachtelten Arrays umgehen möchten, kann dies kompliziert werden.

Für toString verfügt Java.util.Arrays über eine toString(int[]) und andere Überladungen, die Sie verwenden können. Es hat auch deepToString(Object[]) für verschachtelte Arrays.

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

Es wird sehr repetitiv sein (aber sogar Java.util.Arrays ist sehr repetitiv ), aber so ist es in Java mit Arrays.

Siehe auch

62

Auf jedes Element eines Arrays kann mit dem folgenden Code separat zugegriffen werden:

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

Beachten Sie, dass es nicht notwendig ist zu wissen, um welche Art von Array es sich handelt, da dies für jedes Array funktioniert.

28
user1928596

Es gibt keine Untertypenbeziehung zwischen Arrays des primitiven Typs oder zwischen einem Array eines primitiven Typs und einem Array eines Referenztyps. Siehe JLS 4.10.3 .

Daher ist Folgendes zu Testzwecken falsch, um festzustellen, ob obj ein Array irgendeiner Art ist:

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

Insbesondere funktioniert es nicht, wenn obj ein 1-D-Array von Grundelementen ist. (Es funktioniert jedoch für primitive Arrays mit höheren Dimensionen, da alle Array-Typen Untertypen von Object sind. In diesem Fall ist dies jedoch moot.)

Ich benutze Google GWT, also darf ich Reflection nicht verwenden :(

Die beste Lösung (für den Teil isArray der Frage) hängt davon ab, was als "Reflektion verwenden" gilt.

  • In GWT zählt der Aufruf von obj.getClass().isArray() nicht als Reflexion1Das ist also die beste Lösung. 

  • Ansonsten können Sie am besten herausfinden, ob ein Objekt einen Array-Typ hat, indem Sie eine Folge von instanceof-Ausdrücken verwenden. 

    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[];
    }
    
  • Sie können auch versuchen, den Namen der Klasse des Objekts wie folgt zu ändern, aber der Aufruf von obj.getClass() grenzt an die Reflektion.

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

1 - Genauer gesagt, die Class.isArray-Methode wird von GWT in dieser Seite unterstützt aufgelistet.

9
Stephen C

Sie können eine Dienstprogrammklasse erstellen, um zu überprüfen, ob die Klasse ein beliebiges Collection , Map oder Array

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