Java-Array-Reflektion: isArray vs. instanceof

Lesezeit: 4 Minuten

Gibt es einen Präferenz- oder Verhaltensunterschied zwischen der Verwendung von:

if(obj.getClass().isArray()) {}

und

if(obj instanceof Object[]) {}

?

Benutzer-Avatar
Erickson

In den meisten Fällen sollten Sie die verwenden instanceof -Operator, um zu testen, ob ein Objekt ein Array ist.

Im Allgemeinen testen Sie den Typ eines Objekts, bevor Sie ihn auf einen bestimmten Typ umwandeln, der zur Kompilierzeit bekannt ist. Vielleicht haben Sie zum Beispiel Code geschrieben, der mit a arbeiten kann Integer[] oder ein int[]. Sie möchten Ihre Abgüsse mit schützen instanceof:

if (obj instanceof Integer[]) {
    Integer[] array = (Integer[]) obj;
    /* Use the boxed array */
} else if (obj instanceof int[]) {
    int[] array = (int[]) obj;
    /* Use the primitive array */
} else ...

Auf der JVM-Ebene ist die instanceof Operator übersetzt in ein bestimmtes “Instanz von” Byte-Code, der in den meisten JVM-Implementierungen optimiert ist.

In selteneren Fällen verwenden Sie möglicherweise Reflektion, um einen Objektgraphen unbekannten Typs zu durchlaufen. In solchen Fällen ist die isArray() -Methode kann hilfreich sein, da Sie den Komponententyp zur Kompilierzeit nicht kennen; Sie könnten beispielsweise eine Art Serialisierungsmechanismus implementieren und in der Lage sein, jede Komponente des Arrays unabhängig vom Typ an dieselbe Serialisierungsmethode zu übergeben.

Es gibt zwei Sonderfälle: Nullreferenzen und Referenzen auf primitive Arrays.

Eine Nullreferenz wird verursachen instanceof resultieren falsewährend isArray wirft ein NullPointerException.

Angewendet auf ein primitives Array, the instanceof Erträge false es sei denn, der Komponententyp auf dem rechten Operanden stimmt genau mit dem Komponententyp überein. Im Gegensatz, isArray() wird zurückkehren true für jeden Bauteiltyp.

  • Ja, aber wie viel Unterschied wird es machen? Das klingt für mich nach Mikrooptimierung.

    – Michael myers

    20. Oktober 2008 um 21:26 Uhr

  • @Dims Wenn Sie das behaupten obj instanceof int[] Erträge false wenn Sie eine zuweisen int[] zu objdu liegst falsch.

    – Ericsson

    13. Februar 2013 um 16:58 Uhr

  • Entschuldigung, das meinte ich obj instanceof Object[] Erträge false wenn Object obj = new int[7].

    – Dimmt

    13. Februar 2013 um 17:07 Uhr


  • Richtig, in Java sind primitive Datentypen keine Objekte und werden nicht erweitert java.lang.Object, das macht also Sinn. Aber instanceof kann weiterhin zum Testen auf primitive Arrays verwendet werden.

    – Ericsson

    13. Februar 2013 um 17:26 Uhr

  • -1: Allgemein, da primitive Arrays sind Arrays aufrufen isArray() sollte benutzt werden. In der sehr nicht allgemein Sonderfall, nur Arrays von Objekten zu haben, instanceof bietet eine leistungsstarke Alternative.

    – Sam Harwell

    23. April 2013 um 13:34 Uhr

Benutzer-Avatar
Burkhard

Im letzteren Fall, wenn obj null ist, erhalten Sie keine NullPointerException, sondern ein false.

Wenn obj ist vom Typ int[] sagen, dann wird das ein Array haben Class aber keine Instanz von sein Object[]. Also was willst du damit machen obj. Wenn Sie es werfen wollen, machen Sie mit instanceof. Wenn Sie Reflektion verwenden wollen, dann verwenden Sie .getClass().isArray().

Benutzer-Avatar
Sebastien Tardif

getClass().isArray() ist unter Sun Java 5 oder 6 JRE deutlich langsamer als unter IBM.

So viel, dass mit clazz.getName().charAt(0) == '[' is faster on Sun JVM.

user avatar
dturanski

I recently ran into an issue upgrading a Groovy application from JDK 5 to JDK 6. Using isArray() failed in JDK6:

MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...

Changing to instanceof Object[] das behoben.

  • Das macht keinen Sinn. isArray ist eine Methode der Classnicht Typealso natürlich GenericArrayTypeImpl hat diese Methode nicht. Und getClass kann niemals eine Nicht-Class Typealso müssen Sie (oder Groovy??) etwas falsch gemacht haben, um dies zu bekommen, wie zum Beispiel die Annahme von every Type ist ein Class.

    – kaqqao

    8. Dezember 2017 um 13:06 Uhr


Benutzer-Avatar
Bill K

Wenn Sie jemals die Wahl zwischen einer reflektierenden und einer nicht reflektierenden Lösung haben, wählen Sie niemals die reflektierende Lösung (mit Klassenobjekten). Es ist nicht so, dass es „falsch“ oder so wäre, aber alles, was mit Reflexion zu tun hat, ist im Allgemeinen weniger offensichtlich und weniger klar.

  • Das macht keinen Sinn. isArray ist eine Methode der Classnicht Typealso natürlich GenericArrayTypeImpl hat diese Methode nicht. Und getClass kann niemals eine Nicht-Class Typealso müssen Sie (oder Groovy??) etwas falsch gemacht haben, um dies zu bekommen, wie zum Beispiel die Annahme von every Type ist ein Class.

    – kaqqao

    8. Dezember 2017 um 13:06 Uhr


Benutzer-Avatar
Trenton D. Adams

Die Java-Array-Reflektion ist für Fälle gedacht, in denen Sie keine Instanz der Klasse zur Verfügung haben, um “instanceof” auszuführen. Wenn Sie beispielsweise eine Art Injection-Framework schreiben, das Werte in eine neue Instanz einer Klasse einfügt, wie es JPA tut, müssen Sie die isArray()-Funktionalität verwenden.

Ich habe Anfang Dezember darüber gebloggt.
http://blog.adamsbros.org/2010/12/08/java-array-reflection/

1351000cookie-checkJava-Array-Reflektion: isArray vs. instanceof

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy