From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+Auch für das Erzeugen von Arrays und den Zugriff auf ihre Elemente
+stellt Reflection Mechanismen zur Verfügung. Wichtige Voraussetzung
+dafür ist, dass Arrays in Java Objekte sind und ein Array
+somit immer eine Instanz der Klasse Object
+ist, gleich welchen Typs seine Elemente sind. Alle Methoden zum dynamischen
+Zugriff auf Arrays sind in der Klasse Array
+gebündelt, die sich ebenfalls im Paket java.lang.reflect
+befindet. Array
+enthält ausschließlich statische Methoden, die sich grob
+in die beiden Gruppen Erzeugen von Arrays und Zugriff auf
+Array-Elemente einteilen lassen.
+
+
+Um ein Array dynamisch zu erzeugen gibt es in Array
+zwei Methoden mit dem Namen newInstance:
+
+
+Beide Methoden erwarten als erstes Argument ein Klassenobjekt, das
+den Typ der Array-Elemente bestimmt. Dieses kann mit der Methode getClass
+oder - wie in Abschnitt 43.3
+gezeigt - mit der .TYPE- oder .class-Notation erzeugt werden. Als
+zweites Element wird entweder ein einzelner Wert des Typs int
+angegeben, wenn ein eindimensionales Array erzeugt werden soll. Er
+gibt die Anzahl der zu erzeugenden Array-Elemente an. Alternativ kann
+ein int-Array
+übergeben werden, dessen Elementzahl die Anzahl der Dimensionen
+des zu erzeugenden Arrays bestimmt. Jedes Element definiert seinerseits,
+wie viele Elemente die korrespondierende Dimension hat. Der Rückgabewert
+von newInstance
+ist das neu erzeugte Array, typisiert als Object.
+
+
+Wir wollen uns ein einfaches Beispiel ansehen:
+
+
+
+
+
+
+ Titel
+ Inhalt
+ Suchen
+ Index
+ DOC
+ Handbuch der Java-Programmierung, 5. Auflage
+
+ <<
+ <
+ >
+ >>
+ API
+ Kapitel 43 - Reflection
+
+
+
+
+
+43.5 Arrays
+
+
+
+
+
+
+
+43.5.1 Erzeugen von Arrays
+
+
+
+
+
+
+
+
+
+
+public static Object newInstance(Class componentType, int length)
+ throws NegativeArraySizeException
+
+public static Object newInstance(Class componentType, int[] dimensions)
+ throws IllegalArgumentException, NegativeArraySizeException
+
+
+
+java.lang.reflect.Array
+
+
+
+Listing 43.8: Erzeugen von Arrays per Reflection
+
+
+
+
+
+001 /* Listing4308.java */
+002
+003 import java.lang.reflect.*;
+004
+005 public class Listing4308
+006 {
+007 public static void createArray1()
+008 {
+009 //Erzeugt ein eindimensionales int-Array
+010 Object ar = Array.newInstance(Integer.TYPE, 3);
+011 int[] iar = (int[])ar;
+012 for (int i = 0; i < iar.length; ++i) {
+013 iar[i] = i;
+014 System.out.println(iar[i]);
+015 };
+016 }
+017
+018 public static void createArray2()
+019 {
+020 //Erzeugt ein zweidimensionales String-Array
+021 Object ar = Array.newInstance(String.class, new int[]{7, 4});
+022 String[][] sar = (String[][])ar;
+023 for (int i = 0; i < sar.length; ++i) {
+024 for (int j = 0; j < sar[i].length; ++j) {
+025 sar[i][j] = "(" + i + "," + j + ")";
+026 System.out.print(sar[i][j] + " ");
+027 }
+028 System.out.println();
+029 };
+030 }
+031
+032 public static void main(String[] args)
+033 {
+034 createArray1();
+035 System.out.println("--");
+036 createArray2();
+037 }
+038 }
+
+
+Listing4308.java
+
+In Zeile 010 wird ein eindimensionales +int-Array +mit drei Elementen erzeugt, das zunächst vom Typ Object +ist. Um zu zeigen, dass es sich tatsächlich um ein derartiges +Array handelt, führen wir in der nächsten Zeile eine Typkonvertierung +auf int[] durch und weisen es +der Hilfsvariablen iar zu, auf +der auch alle weiteren Zugriffe auf das Array erfolgen. + +
+Analog wird in Zeile 021
+ein weiteres Array erzeugt. Es ist ein zweidimensionales Array vom
+Typ String,
+das sieben Zeilen und vier Spalten besitzt. Auch hier wird in der
+nächsten Zeile eine Typkonvertierung vorgenommen, damit die anschließenden
+Zugriffe bequem erfolgen können. Die Ausgabe des Programms lautet:
+
+
+0
+1
+2
+--
+(0,0) (0,1) (0,2) (0,3)
+(1,0) (1,1) (1,2) (1,3)
+(2,0) (2,1) (2,2) (2,3)
+(3,0) (3,1) (3,2) (3,3)
+(4,0) (4,1) (4,2) (4,3)
+(5,0) (5,1) (5,2) (5,3)
+(6,0) (6,1) (6,2) (6,3)
+
+
+
+
+
+
+
+Während wir im vorigen Beispiel noch mit der schon aus Abschnitt 5.7.2 +bekannten []-Notation auf die Elemente der per Reflection erzeugten +Arrays zugegriffen haben, wollen wir uns in diesem Abschnitt ansehen, +wie auch die Elementzugriffe vollkommen dynamisch durchgeführt +werden können. Dazu stellt die Klasse Array +folgende Methoden zur Verfügung: +
+
+
++public static Object get(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void set(Object array, int index, object value) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static int getLength(Object array) + throws IllegalArgumentException ++ + |
++java.lang.reflect.Array | +
+Mit get +kann auf das Element mit dem Index index +des Arrays array zugegriffen +werden. Es wird stets als Object +zurückgegeben, primitive Typen werden in ein Wrapper-Objekt verpackt. +Die Methode set +führt die umgekehrte Funktion aus. Sie speichert den Wert value +an der durch index bezeichneten +Position im Array array. Auch +hier müssen primitive Werte vor der Übergabe in ein Wrapper-Objekt +verpackt werden. Beide Methoden lösen eine Ausnahme aus, wenn +das übergebene Objekt kein Array ist oder ein ungültiger +Index angegeben wird. Schließlich gibt es die Methode getLength, +mit der die Anzahl der Elemente eines Arrays ermittelt werden kann. +
+
![]() |
+
+
+ +Der Zugriff auf mehrdimensionale Arrays erfolgt analog dem statischen +Fall. Auch hier gilt, dass mehrdimensionale Arrays als (ggfs. mehrfach) +geschachtelte eindimensionale Arrays dargestellt werden (siehe Abschnitt 4.4.3). +Soll also beispielsweise ein Element eines zweidimensionalen Arrays +gelesen werden, so sind dazu zwei Aufrufe von get +nötig. Der erste liefert das geschachtelte innere Array, der +zweite wird auf eben dieses Array angewendet und liefert das gewünschte +Element. Bei mehr als zwei Dimensionen sind entsprechend weitere get-Aufrufe +nötig. |
+
+
|
+![]() |
+
+Neben den einfachen get- +und set-Methoden +gibt es weitere, die eine automatische Konvertierung zu primitiven +Datentypen durchführen: + + + + + +
+
+
++public static boolean getBoolean(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static byte getByte(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static char getChar(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static short getShort(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static int getInt(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static long getLong(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static float getFloat(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static double getDouble(Object array, int index) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void setBoolean(Object array, int index, boolean z) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void setByte(Object array, int index, byte b) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void setChar(Object array, int index, char c) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void setShort(Object array, int index, short s) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void setInt(Object array, int index, int i) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void setLong(Object array, int index, long l) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void setFloat(Object array, int index, float f) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException + +public static void setDouble(Object array, int index, double d) + throws IllegalArgumentException, ArrayIndexOutOfBoundsException ++ + |
++java.lang.reflect.Array | +
+Das folgende Beispiel zeigt die Anwendung der get- +und set-Methoden +auf ein dynamisch erzeugtes Array: + + +
+
+
+
+001 /* Listing4309.java */
+002
+003 import java.lang.reflect.*;
+004
+005 public class Listing4309
+006 {
+007 public static void createArray1()
+008 {
+009 //Erzeugt ein eindimensionales int-Array
+010 Object ar = Array.newInstance(Integer.TYPE, 3);
+011 for (int i = 0; i < Array.getLength(ar); ++i) {
+012 Array.set(ar, i, new Integer(i));
+013 System.out.println(Array.getInt(ar, i));
+014 };
+015 }
+016
+017 public static void createArray2()
+018 {
+019 //Erzeugt ein zweidimensionales String-Array
+020 Object ar = Array.newInstance(String.class, new int[]{7, 4});
+021 for (int i = 0; i < Array.getLength(ar); ++i) {
+022 Object subArray = Array.get(ar, i);
+023 for (int j = 0; j < Array.getLength(subArray); ++j) {
+024 String value = "(" + i + "," + j + ")";
+025 Array.set(subArray, j, value);
+026 System.out.print(Array.get(subArray, j) + " ");
+027 }
+028 System.out.println();
+029 };
+030 }
+031
+032 public static void main(String[] args)
+033 {
+034 createArray1();
+035 System.out.println("--");
+036 createArray2();
+037 }
+038 }
+
+ |
++Listing4309.java | +
+Der Hauptunterschied zum vorigen Beispiel liegt darin, dass die Elemente +der Arrays nunmehr ausschließlich mit Methoden der Klasse Array +gesetzt und abgefragt werden. In createArray1 +ist es nötig, den int-Wert +beim Aufruf der set-Methode +in einen Integer-Wrapper +zu verpacken; das Auslesen erfolgt dagegen typkonform mit der Methode +getInt. + +
+In createArray2 wird jedes Element +des äußeren Arrays zunächst in der Variablen subArray +gespeichert. Da das Hauptarray ar +zweidimensional ist, stellt subArray +de facto ein eindimensionales String-Array +dar, auf das in den folgenden Zeilen direkt mit get +und set +zugegriffen werden kann. + +
+Die Ausgabe des Programms ist identisch mit der des vorigen Beispiels:
+
+
+0
+1
+2
+--
+(0,0) (0,1) (0,2) (0,3)
+(1,0) (1,1) (1,2) (1,3)
+(2,0) (2,1) (2,2) (2,3)
+(3,0) (3,1) (3,2) (3,3)
+(4,0) (4,1) (4,2) (4,3)
+(5,0) (5,1) (5,2) (5,3)
+(6,0) (6,1) (6,2) (6,3)
+
+
+
| Titel + | Inhalt + | Suchen + | Index + | DOC + | Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 + |
| << + | < + | > + | >> + | API + | © 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de + |