2012-10-06 5 views
15

Ich verstehe, dass Arrays Objekte in Java und daher eine Unterklasse des Objekttyps sind. Mein weiteres Verständnis ist, dass ein 2-Dim-Array als ein Array von Referenzen auf Arrays implementiert ist. Deshalb verstehe ich nicht, warum mein a [0] [0] im obigen Code nicht bar produziert. Stattdessen hat kompiliert es nicht:Objekttyp in Java und referenzierende Arrays

RefMix.java:7: array required, but java.lang.Object found 

Antwort

13

Mein Verständnis ist, dass Arrays Objekte in Java und daher eine Unterklasse des Objekttyps sind. Mein weiteres Verständnis ist, dass ein 2-Dim-Array als ein Array von Referenzen auf Arrays implementiert ist.

Das alles korrekt ist, und erklärt, warum Sie die Zuordnung tun

a[0] = b; 

ohne Beanstandungen vom Compiler.

Deshalb verstehe ich nicht, warum meine a [0] [0] im obigen Code keine Balken erzeugt.

Okay, schauen wir uns die Typen in dieser Ausdruck einen Blick:

  • a ist ein Object[] -, dass eine Reihe von Object s
  • a[0] ein Object
  • a[0][0] ist - - Jetzt versuchen Sie, einen Array-Index auf einem Object zu verwenden. Der Compiler weiß nicht, dass das Object tatsächlich ein Array ist, also klagt es.
10

Der Laufzeittyp einer Objektinstanz vom Typ statisch abgeleitet unterscheidet. Der Compiler versucht zu schätzen, welchen Typ jede Variable im Programm haben könnte, um bestimmte Arten von Fehlern frühzeitig zu erkennen. In diesem Fall wird a[0] immer ein Array sein, aber der Compiler weiß das nicht. Da Sie ein Objekt aus einem Objekt-Array erhalten, weiß der Compiler, dass a[0] ein Objekt ist. Daher wird ein Fehler angezeigt.

In Fällen, in denen Sie wissen, dass etwas immer ein bestimmter Typ sein wird, aber der Compiler es nicht herausfinden kann, können Sie dies umgehen, indem Sie eine explizite Umwandlung einfügen.

System.out.println(((Object[])a[0])[0]); 
+0

Die Hässlichkeit einer Besetzung wie diese hat mich dazu inspiriert, solche Arrays zu verwenden; Ich werde nur eine "normale" Klasse von Objektreferenzen verwenden. Aber danke! – Fixee

+3

@Fixee, Arrays in Java sind eher hässlich, aber Sie können oft die Notwendigkeit von Umwandlungen vermeiden, indem Sie die Anzahl der Speichervorgänge für heterogene Daten reduzieren. In der Regel müssen Sie weder Strings noch Objekt [] s im selben Array speichern. – Antimony

+2

@Antimony Ich kann eigentlich keinen einzigen Anwendungsfall finden, wo du * so etwas * brauchen würdest ...;) – brimborium

4

Da Array in Java ein Objekt ist, so dass die erste und zweite Zuordnung, speichert Ihr Array als erstes Element des Object-Array ..

Object[] a = {null, "foo"}; 
Object[] b = {"bar", b}; 

Jetzt haben Sie Ihre erste geändert Element von a Objekt-Array, um den Wert b anstelle von Array enthalten .. Aber da es ein Array von Objekt ist. aus ihm wird alles kommt Objekt sein ..

Da a [0] ein Objekt .. So kann man natürlich nicht so etwas wie dieses zugreifen: -

System.out.println(a[0][0]); 

Sie können versuchen, typisieren Ihr Objekt a [0] Array Objekt ..: -

System.out.println(((Object[])a[0])[0]); 
4

Do:

System.out.println(((Object[])a[0])[0]); 

Diese "wirft" das Objekt zur Laufzeit in ein Objektarray.

7

Sie haben Recht, Arrays sind immer Objects in Java, aber Objects sind nicht immer Arrays, also Sie einen Compiler-Fehler erhalten, weil a ist ein Object[] (eindimensional). Sie können nicht

a[0][0]; 

zugreifen, da a nicht eine zweidimensionale Anordnung ist (zumindest ist es nicht als solche deklariert). In diesem Fall sind Sie jedoch sicher, dass a[0] ein Array von Objects ist. Daher können Sie dies tun:

Object[] c = (Object[]) a[0]; 
System.out.println(c[0]); 
// or directly: 
System.out.println(((Object[])a[0])[0]); 

Diese wirft den Rückgabetyp von a[0] (die Object ist) in einen Object[] und Sie können dann die „zweite Schicht“ Zugriff des Arrays.

1

Alles, was Sie tun, ist äquivalent zu diesem

Object a = {"bar", "foo"}; 
System.out.println(a[0]); 

welche ebenfalls nicht kompilieren.

2

Da ich in letzter Zeit eine Menge C + + -Codierung mache, finde ich, dass Java bei der Typüberprüfung viel strenger ist als C++. Java sieht alles außer primitiven Typen als Objekt, aber Java geht noch einen Schritt weiter bei der Unterscheidung von Array- und Nicht-Array-Typen. Während der Zuweisung wie "a [0] = b;" , Java prüft zuerst, ob es sich um einen Array-Typ handelt oder nicht, danach wird der normale polymorphe Typ überprüft. Wenn Sie Ihren Code Arbeit machen, sollten Sie tun, ...

Object[][] a = {{null}, {"foo"}}; 
Object[] b = {"bar", new java.util.Date()}; 
a[0] = b; 

können Sie sehen, wie besondere Sorgfalt auf Array-Typen nehmen Java von der Suche in Java-Klassensignatur, die Class.forName() als Parameter übergeben wird . Zum Beispiel Datentyp ..

com.foo.Bar[][] barsIn2D; 

mit Unterschrift geladen ...

// [ => Array 
// [[ => Array of Array type 
// L<object>; => Object, not Array 
Class.forName("[[Lcom/foo/Bar;"); 

Wie Sie sehen, Unterschrift beginnt entweder mit '[' oder 'L'. Dies sagt uns, ob es ein Array oder nicht hat Vorrang vor "Lcom/foo/Bar;".