Von Datentypen und (mehrdimensionalen) Arrays

mihe7

Top Contributor
Da es insbesondere im Zusammenhang mit mehrdimensionalen Arrays immer wieder zu Verwirrungen kommt, hier mal ein "Crashkurs" zum Thema "was passiert eigentlich in meinem Speicher?"

Da für das Verständnis Modelle ungemein helfen, wollen wir uns den Arbeitsspeicher einfach als eine Menge von Bytes darstellen, die nacheinander angeordnet sind. Bildlich kann man sich einen n-Byte großen Arbeitsspeicher somit wie folgt vorstellen:
memory.gif
Wie dort angedeutet, kann man die "Speicherzellen" durchnummerieren und erhält auf diese Weise einen linearen Adressraum. Die Adresse j entspricht also der (j+1)-ten Zelle des Speichers. Wir nehmen im Folgenden an, dass eine Zelle genau einem Byte entspricht.

Nun ist klar, dass für Daten unterschiedlicher Art auch unterschiedlich viel Platz im Speicher benötigt wird. Des weiteren stellt sich die Frage, wie Informationen binär repräsentiert werden sollen. Beispielsweise kann man sich fragen, wie man negative Zahlen mit Hilfe von Bytes darstellen möchte. Gott sei Dank müssen wir uns um viele Details nicht kümmern, denn einige Arten von Daten sind derart elementar, dass es bereits vordefinierte Datentypen gibt, die z. T. auch von der Hardware unterstützt werden.

Diese elementaren Datentypen zeichnen sich dadurch aus, dass sie einen definierten Wertebereich und damit auch eine feste Größe (Anzahl an Bytes) besitzen. Die primitiven Datentypen, wie sie in Java auch genannt werden, stellen letztlich die Grundbausteine für den Aufbau komplexer Datentypen dar.

In Java existiert eine Reihe primitiver Datentypen, wozu auch der Typ int gehört, mit dem wir uns im Folgenden beispielhaft beschäftigen wollen. Durch den Datentyp int ist in Java(!) festgelegt, dass ganzzahlige Werte im Zweierkomplement mit 32 Bit gespeichert werden (Details: Suchmaschine des Vertrauens nutzen). Der Wertebereich umfasst somit -2^31 bis +2^31-1. In anderen Sprachen fällt die Definition ggf. anders aus, z. B. hängt in C vieles von der Umgebung (wie Hardware) ab, unter der bzw. für die ein Programm übersetzt wird.

Die Größe des Datentyps int beträgt in Java also fix 4 Bytes (32 Bit). D. h. ein int-Wert befindet sich in unserem Modell irgendwo im Speicher und belegt dort immer 4 Bytes. Das folgende Bild zeigt die Belegung durch ein int an Adresse 20 (grün).
memory_int.gif
Eine int-Variable steht nun im Code einfach stellvertretend für den Speicherbereich, in dem der Wert im Speicher gehalten wird. Das gilt auch für jeden anderen primitiven Datentyp. Hat man zwei int-Variablen, so stehen diese für zwei unterschiedliche Speicherbereiche, wie das folgende Bild für int a; und int b; zeigt.
memory_int_copy1.gif
Weist man den Wert einer Variablen einer anderen zu (a = b;), wird der Wert von einem Bereich in den anderen kopiert:

memory_int_copy2.gif
Kommen wir nun zu einem etwas komplexeren Typ, dem Array. Ein eindimensionales Array ist nichts anderes als ein zusammenhängender Speicherbereich, der für eine bestimmte Zahl an Elementen gleichen Typs reserviert wird. Für die Erzeugung eines Arrays werden also Datentyp und Zahl der Elemente (Länge des Arrays) benötigt.

Ein Array für Elemente des Datentyps int (kurz: int-Array) der Länge 9 können wir uns wie folgt vorstellen:

memory_int_arr.gif
Der Vorteil ist nun, dass sich die Adresse eines jeden Elements im Speicher sofort berechnen lässt. Dazu multipliziert man einach den Index des gewünschten Elements mit der Größe des Datentyps und addiert die Startadresse des Arrays. Will man z. B. das vierte Element (Index 3) im int-Array (int -> 4-Bytes/Element), dann befindet sich dieses 3*4 = 12 Bytes von der Startadresse des Arrays entfernt. Da die Startadresse im Beispiel 2 beträgt, findet sich das Element also bei Adresse 12+2 = 14.

Ein solches Array wird in Java mittels new int[9]; erzeugt. Mit dieser Anweisung wird der Speicher für ein int-Array der Länge 9 reserviert. Um dieses Array im Code ansprechen zu können, müssen wir uns aber die Startadresse merken, d. h. wir brauchen eine Variable, der wir die Startadresse des Arrays zuweisen können. Im Code sieht das nun folgendermaßen aus int[] arr = new int[9].

In arr wird also die Adresse gespeichert, an der das Array im Speicher zu finden ist. Der Index-Operator [] sorgt nun dafür, dass die Adresse des gewünschten Elements berechnet wird, so dass mit arr[3] auf das vierte Element des Arrays zugegriffen wird.

D. h. arr steht nicht für den Speicherbereich, in dem das Array selbst im Speicher gehalten wird, sondern für den Bereich, an dem die Startadresse des Arrays abgelegt wird bzw. wurde. Damit speichert arr also nicht das Array sondern eine Referenz auf das Array. Wie viele Bytes eine solche Adresse in Java im Speicher belegt, ist nicht definiert, sondern von der jeweiligen Implementierung (ggf. auch fallweise) der Java Virtual Machine (JVM) abhängig. Für unsere Überlegungen nehmen wir der Einfacheit eine 32-Bit-JVM an, die 4 Bytes für eine Adresse reserviert.

Das Verständnis für die Referenzierung ist essenziell, da sie nicht nur Arrays sondern alle komplexen Typen (z. B. Objekte) betrifft und entsprechende Folgen nach sich zieht. Hätten wir z. B. zwei int[]-Variablen a und b und würden a=b; schreiben, dann würde der Speicherbereich, für den b steht, in den Bereich, für den a steht, kopiert werden. Da dort aber nur Adressen gespeichert sind, wird auch nur eine Adresse (und nicht das Array) kopiert. Am Ende referenzieren beide Variablen das selbe Array, das nur einmal im Speicher existiert.

Wie sieht es nun mit mehrdimensionalen Arrays aus? Hier gibt es zwei Möglichkeiten. Dazu betrachten wir ein zweidimensionales int-Array, sagen wir mal der Größe 3x3, das wir als int-Array mit 3 Zeilen je 3 Spalten auffassen können. Die erste Möglichkeit besteht darin, das Array in einen zusammenhängenden Speicherbereich abzubilden. Dazu reservieren genug Speicherplatz für 3*3=9 Elemente und können die Zeilen des Arrays einfach hintereinander im Speicher ablegen. Das Ergebnis sieht dann genauso aus wie unser eindimensionales Array der Länge 9. Der Index-Operator führt dann einfach zu einer anderen Berechnung der Adresse eines Elements: für [zeile][spalte] würde dann einfach zeile*<Breite des Arrays in Bytes> + spalte*<Größe des Datentyps in Bytes> + <Startadresse des Arrays> ausreichen.

Java verfolgt einen anderen Ansatz, bei dem mehrdimensionale Arrays einfach als Array von (Adressen anderer) Arrays betrachtet werden. Das 3x3-Array wäre also ein Array, das die Adressen zu drei anderen Arrays aufnimmt. Diese können nun alle die Länge 3 haben - dann hat man ein 3x3-Array - müssen aber nicht. Der Vorteil ist, dass jedes Array einen von den anderen Arrays unabhängigen Speicherbereich belegt und in der Größe ebenfalls unabhängig ist. Nachteilig ist dagegen, dass man sich durch mehrere Arrays hangeln muss, bis man das gewünschten Element erhält.

In unserem Modell-Speicher benötigen wir also 3*4=12 Bytes für das Array, das die Adressen (je 4 Bytes) der 3 weiteren Arrays speichert, außerdem würde jedes dieser drei Arrays drei int-Werte (je 4 Bytes) und damit wiederum 12 Bytes belegen. Insgesamt benötigen wir also 48 Bytes:

memory_int_arr2d.gif
Die Speicherbereiche, die Adressen speichern, sind im Bild mit Blautönen hervorgehoben, für die int-Werte wurden wieder die Farben grün und rot verwendet. An Adresse 2 beginnt im Bild das Array, das die Adressen der drei anderen Arrays speichert. In diesem Array finden sich also die Einträge $44, $30 und $16 (das $ soll anzeigen, dass es sich um eine Adresse handelt), im Bild durch Pfeile dargestellt.

Die Angabe arr[1][2] kann nun beispielsweise von rechts nach links derart gelesen werden, dass das dritte Element (Index 2) des Arrays gesucht wird, auf das das zweite Element (Index 1) des Arrays arr verweist.

Um nun das Element arr[1][2] zu erhalten, wird zunächst im Array arr das Element mit Index 1 gelesen. Dabei handelt es sich um die Startadresse eines Arrays, mit deren Hilfe die Adresse des Zielelements ermittelt wird. Auf das Bild bezogen würde also zunächst die Adresse $30 (Index 1) aus dem ersten Array gelesen, womit die Adresse des gewünschten Elements berechnet werden kann: 30 + 2*4 = 38.

Da in Java ein mehrdimensionales Array ein Array von Arrays ist, braucht man nicht die Größen aller Dimensionen anzugeben. Es reicht, bei der Initialisierung die Zahl der Arrays anzugeben, die im Array gespeichert werden sollen, z. B. reserviert int[][] arr = new int[10][]; Platz für ein Array, das die Adressen von 10 int-Arrays aufnehmen kann. In dem Fall sind die 10 Adressen zunächst mit null initialisiert. Man muss nun jedes Array separat initialisieren und zuweisen, so wäre arr[0] = new int[3]; und arr[5] = new int[214]; möglich. Das mehrdimensionale Array ist nun also nicht mehr "rechteckig".

Das Speichern von Referenzen in einem Array wird in Java nicht nur bei mehrdimensionalen Arrays angewandt, vielmehr werden solche Verweise für alle Objekte im Speicher verwaltet. Ein Array ist in Java nämlich nichts anderes als ein spezielles Objekt (unsere modellhafte Darstellung von Arrays enttspricht also nicht den tatsächlichen Gegebenheiten, da Java für Objekte etwas mehr im Speicher ablegt).

Führt man beispielsweise String name = new String("ABC"); aus, dann steht die Variable name nicht für den Speicherbereich des String-Objekts "ABC", sondern für einen Speicherbereich, in dem die Adresse des String-Objekts abgelegt wird. Damit wird auch hier mit der Anweisung String name2 = name; nicht etwa das Objekt selbst, sondern lediglich die Adresse kopiert, die in name zum Zeitpunkt der Ausführung gespeichert ist. Man sieht, das läuft völlig analog zum Array ab.

Damit lassen sich nun einige Dinge leicht erklären: der Vergleich a == b liefert true, wenn die Speicherbereiche von a und b den gleichen Inhalt haben. Bei primitiven Datentypen entspricht das einfach dem gespeicherten Wert. Bei komplexen Datentypen stehen dort aber Adressen, so dass in diesem Fall Referenzen miteinander verglichen werden.

Java:
// Primitive Typen
int a = 5;
int b = 10;
System.out.println(a == b); // false, denn a steht für die 5, b für die 10
a = b; // kopiere den Wert von b (10) nach a
System.out.println(a == b); // true, denn 10 == 10

// Komplexe Typen
String name1 = new String("ABC"); // name1 speichert Adresse x des neu erzeugten Strings
String name2 = new String("ABC"); // name2 speichert Adresse y des neu erzeugten Strings
System.out.println(name1 == name2); // false, denn name1 steht für x und name2 für y
name1 = name2; // kopiert den Wert von name2 (Adresse y) nach name1
System.out.println(name1 == name2); // true, denn name1 und name2 stehen für Adresse y

Ein anderes Beispiel betrifft das Kopieren von Arrays mittels z. B. System.arraycopy oder Arrays.copyOf: hat man ein Array eines komplexen Typs, werden im Array die Speicheradressen abgelegt. Kopiert werden also nur die Adressen, nicht die Objekte selbst. Man spricht in dem Zusammenhang auch von flacher Kopie (shallow copy).
 
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Datentypen Das Verhalten von Strings als Datentypen Java Basics - Anfänger-Themen 7
T Unterschiedliche Datentypen - worin abspeichern? Java Basics - Anfänger-Themen 18
N Verschiedene Konstruktoren mit gleichen Datentypen Java Basics - Anfänger-Themen 8
J Einige Anfängerfragen (Datentypen, Wertebereich) Java Basics - Anfänger-Themen 11
thor_norsk Datentypen unter Java Java Basics - Anfänger-Themen 3
T Datentypen Eigene Datentypen Java Basics - Anfänger-Themen 15
T for-each-Schleife, verschiedene Datentypen Java Basics - Anfänger-Themen 1
G Methoden Methoden mit versch. Datentypen Java Basics - Anfänger-Themen 1
Nicolex3 Größere Datentypen Java Basics - Anfänger-Themen 35
FelixN Array mit verschiedene Datentypen als Rückgabewert? (Long und Double) Java Basics - Anfänger-Themen 3
P Datentypen, Klassen, Operatoren, Wrapperklassen Java Basics - Anfänger-Themen 2
W Vergleiche bei generischen Datentypen Java Basics - Anfänger-Themen 7
D Eingabe einscannen, ohne vorher einen Datentypen anzugeben? Java Basics - Anfänger-Themen 1
M Datentypen Generische Datentypen - Syntax Java Basics - Anfänger-Themen 25
L Binären Bäume für beliebige Datentypen Java Basics - Anfänger-Themen 15
L Datentypen Ausgabe von eigenem Datentypen Java Basics - Anfänger-Themen 2
T Datentypen Kann Java 2 verschiedene Datentypen vergleichen? Java Basics - Anfänger-Themen 2
A Datentypen Unterschiedliche Datentypen in einer Eingabe einlesen Java Basics - Anfänger-Themen 2
Queiser Datentypen 2 generische Datentypen für eine Schnittstelle Java Basics - Anfänger-Themen 1
SHasteCode Datentypen Überlauf primitiver Datentypen Java Basics - Anfänger-Themen 4
S Datentypen Java Basics - Anfänger-Themen 14
Antegra Tekkrebell Primitive Datentypen Literal 8072 Java Basics - Anfänger-Themen 21
N Array gleiche Datentypen zusammenrechnen Java Basics - Anfänger-Themen 28
S Datentypen Java Basics - Anfänger-Themen 4
S generische methode mit verschiedenen datentypen Java Basics - Anfänger-Themen 3
H wählen des kleinstmöglichen Datentypen für Gleitkommazahlen. Java Basics - Anfänger-Themen 2
S Datentypen Java Basics - Anfänger-Themen 2
S Datentypen Abstrakte Datentypen Java Basics - Anfänger-Themen 0
J Zusammenhang Numbers und nummerische Datentypen Java Basics - Anfänger-Themen 2
F Variablen unterschiedlicher Datentypen Java Basics - Anfänger-Themen 6
A Abstrakte Datentypen - Methode delete Java Basics - Anfänger-Themen 6
J Generics Datentypen vergleichen Java Basics - Anfänger-Themen 16
D Spezifikation abstrakter Datentypen Java Basics - Anfänger-Themen 3
W Datentypen Datentypen vergleichen Java Basics - Anfänger-Themen 4
B JAVA Datentypen/Überlauf Java Basics - Anfänger-Themen 4
I Erste Schritte HILFE bei Datentypen Java Basics - Anfänger-Themen 2
J Wertebereiche und Datentypen Java Basics - Anfänger-Themen 12
N Methode mit 2 Datentypen. Fehler? Java Basics - Anfänger-Themen 1
N Probleme mit Datentypen Java Basics - Anfänger-Themen 6
S Datentypen Unterschied elementare und zusammengesetzte/strukturierte Datentypen Java Basics - Anfänger-Themen 5
L Beliebigen Datentypen aus String parsen Java Basics - Anfänger-Themen 6
M Wann eine Wrapper Klasse verwenden und wann einen primitiven Datentypen? Java Basics - Anfänger-Themen 8
K new / Datentypen Java Basics - Anfänger-Themen 3
S Datentypen und ihre Größe Java Basics - Anfänger-Themen 21
T Variablen Varargs und beliebige Datentypen Java Basics - Anfänger-Themen 7
S Datentypen Sonderbehandlung primitiver Datentypen, fixe Konstanteninterpretation Java Basics - Anfänger-Themen 10
G Wertebereiche bei Datentypen Java Basics - Anfänger-Themen 10
G Erste Schritte Über verschiedene Datentypen iterieren. Gibt es sowas? Java Basics - Anfänger-Themen 19
SheldoN Gibt es größere Datentypen als long? Java Basics - Anfänger-Themen 2
S Abfrage Objekt-Array nach Datentypen Java Basics - Anfänger-Themen 6
B Variablen Wie macht man eine call by reference mit primitiven Datentypen in Java? Java Basics - Anfänger-Themen 2
H Mehrer Datentypen aus einer Methode ausgeben. Java Basics - Anfänger-Themen 25
O Array mit unterschiedlichen Datentypen ausgeben... Java Basics - Anfänger-Themen 16
A Generische Datentypen Java Basics - Anfänger-Themen 8
R Input/Output verschiedene Datentypen als Bytes in Datei speichern Java Basics - Anfänger-Themen 15
T ArrayList mit verschiedenen Datentypen verhindern Java Basics - Anfänger-Themen 8
N Bedingung für Datentypen Java Basics - Anfänger-Themen 3
R Array aus verschiedenen Datentypen Java Basics - Anfänger-Themen 29
J Datentypen Datentypen Java Basics - Anfänger-Themen 7
S Datentypen Array fill Methode - unterschiedliche Datentypen Java Basics - Anfänger-Themen 6
H null und primitive Datentypen Java Basics - Anfänger-Themen 6
N ArrayList mit eigenem Datentypen Java Basics - Anfänger-Themen 3
B Wie kann ich unterschiedliche Datentypen in einem Feld abbilden? Java Basics - Anfänger-Themen 5
S Datentypen Die verschiedene Java Datentypen [Anfänger] Java Basics - Anfänger-Themen 8
M Frage zu Datentypen Java Basics - Anfänger-Themen 4
B Welcher Feld Typ für verschiedene Datentypen? Java Basics - Anfänger-Themen 4
O Rückgabewert mit unterschiedlichen Datentypen Java Basics - Anfänger-Themen 10
S Nicht Primitive Datentypen Java Basics - Anfänger-Themen 5
C Verwendung von primitiven Datentypen Java Basics - Anfänger-Themen 8
Spin Eigenen Abstrakten Datentypen Java Basics - Anfänger-Themen 28
J Datentypen Rechnen mit unterschiedlichen Datentypen Java Basics - Anfänger-Themen 3
B Wieviele bits belegen die Datentypen? Java Basics - Anfänger-Themen 2
S Alle Datentypen in byte Array und zurückwandeln Java Basics - Anfänger-Themen 2
C Explizite und implizite Datentypen Java Basics - Anfänger-Themen 12
F primitive Datentypen, String, Klassen Java Basics - Anfänger-Themen 16
Povlsen84 HashSet mit eigenen Datentypen Java Basics - Anfänger-Themen 6
J Verschieden Datentypen in ein "Array" Java Basics - Anfänger-Themen 13
M HashMap mit primitiven Datentypen Java Basics - Anfänger-Themen 10
SebSnake Operatoren für eigene Datentypen Java Basics - Anfänger-Themen 3
G Frage zum Ungang mit Generische Datentypen Java Basics - Anfänger-Themen 4
G Überladen von Konstruktoren mit unterschiedlichen Datentypen Java Basics - Anfänger-Themen 4
R datentypen konvertierung u modulorechnung Java Basics - Anfänger-Themen 15
G primitive Datentypen als Referenz an eine Methode übergeben Java Basics - Anfänger-Themen 2
G Wertebereiche und Datentypen Java Basics - Anfänger-Themen 3
W Datentypen in JAva Java Basics - Anfänger-Themen 2
G verschiedene datentypen in arraylist Java Basics - Anfänger-Themen 14
N Problem mit Tastatureingaben für verschiedene Datentypen Java Basics - Anfänger-Themen 3
I Array für verschiedene Datentypen? Java Basics - Anfänger-Themen 5
E Eigenen datentypen erstellen Java Basics - Anfänger-Themen 14
Y Neuen Datentypen erstellen Java Basics - Anfänger-Themen 12
M int toString Datentypen Umwandeln, AnfängerProblem Java Basics - Anfänger-Themen 3
M Datentypen zu erzeugen? Java Basics - Anfänger-Themen 2
S Switch für komplexe Datentypen? Java Basics - Anfänger-Themen 7
7 Datentypen Java Basics - Anfänger-Themen 8
S Array mit mehreren Datentypen Java Basics - Anfänger-Themen 5
D String in einen primitiven datentypen parsen Java Basics - Anfänger-Themen 3
F Einlesen von verschieden Datentypen Java Basics - Anfänger-Themen 15
G Verschiedene Datentypen in Vector packen und zurück Java Basics - Anfänger-Themen 3
G Datentypen Java Basics - Anfänger-Themen 2
D Datentypen umwandeln Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben