die Grundidee der Von-Neumann-Architektur erklären,
Speicher als Modell aus Adresse und Daten beschreiben,
Speicherabbilder für Objekte und Referenzen zeichnen und lesen,
Setter und Getter für Referenz-Attribute implementieren,
analysieren, ob eine Methode das übergebene Objekt verändert oder nur die lokale Referenz umbiegt,
begründen, warum getPilot() Zugriff auf das Original-Objekt gibt, nicht auf eine Kopie.
Leitfrage: Wie sieht eine Referenz im Speicher tatsächlich aus — und was passiert, wenn du sie an eine Methode weitergibst?
Voraussetzungen
Hinweis
Dieses Kapitel baut direkt auf Kapitel 01 (Referenzen verstehen) auf.
Du solltest Aliasing, null und den Unterschied == vs. .equals() sicher beherrschen.
Übergang aus dem letzten Kapitel
Im letzten Kapitel hast du gelernt: Eine Referenz ist wie ein Pfeil auf ein Objekt. Dieses Bild erklärt Aliasing gut, aber es ist noch ungenau.
Jetzt wird der Pfeil entzaubert: Im Speicher ist eine Referenz eine Adresse. Die Frage lautet nicht mehr nur „Worauf zeigt die Variable?", sondern: Welche Adresse steht in der Variable und welches Objekt liegt an dieser Adresse?
Phase 1: Einstieg — Was IST eine Referenz im Speicher?
Hinweis
Retrieval-Check (ohne nachschauen):
Was kopiert rs2 = rs1 — das Objekt oder den Pfeil?
Was ist der Unterschied zwischen einfachen und komplexen Datentypen im Speicher?
Was passiert bei rs.setGroesse(200), wenn rs auf null zeigt?
Aufgabe: Vorhersage
Lies den folgenden Code. Was erwartest du — true oder false bei den Vergleichen?
Raumschiff rs1 = new Raumschiff();Raumschiff rs2 = rs1;System.out.println(rs1 == rs2);rs2 = new Raumschiff();System.out.println(rs1 == rs2);
Tipp
Schreibe deine Vermutung auf, bevor du den Code ausführst.
Textabgabe
IDE lädt…
Phase 2: Konzeptaufbau — Vom Speicher zur Praxis
2.1 Von-Neumann-Architektur
Die zentrale Idee: Programme und Daten liegen im selben Speicher (RAM). Die CPU holt Befehle und Daten, verarbeitet sie und schreibt Ergebnisse zurück.
Komponente
Aufgabe
Steuerwerk
Führt Befehle in der richtigen Reihenfolge aus
ALU
Rechnet und vergleicht Werte
Speicher (RAM)
Speichert Programme und Daten während der Ausführung
Ein-/Ausgabe
Austausch mit Tastatur, Bildschirm, Dateien
2.2 Speicher als Adress-/Daten-Tabelle
Der RAM ist eine große Folge von Speicherzellen. Jede Zelle hat eine Adresse und speichert Bytes:
Adresse
Daten
Interpretation
0x100
0x3A8
Referenz rs1 → zeigt auf Adresse 0x3A8
0x108
0x3A8
Referenz rs2 → zeigt auf dieselbe Adresse!
...
...
...
0x3A8
200.0
Attribut groesse des Raumschiff-Objekts
Hinweis
Kernaussage: Eine Referenz speichert eine Adresse — eine Zahl, die sagt, WO das Objekt im RAM liegt. rs2 = rs1 kopiert diese Adresse, nicht das Objekt.
Achtung
Dieselben Bytes im Speicher können je nach Kontext eine Zahl, ein Zeichen oder eine Adresse bedeuten. Die Interpretation ergibt sich erst durch den Datentyp im Programm.
Reflexionsfrage: Warum speichert Java nicht einfach das ganze Objekt in der Variablen, statt nur eine Adresse?
Bisher hatten wir Referenzen in der Hauptklasse (WeltraumSim → Raumschiff). Aber was, wenn das Raumschiff selbst wissen soll, wer es fliegt?
Dafür bekommt Raumschiff ein Referenz-Attribut:
Mermaid-Diagramm
Mermaid-Diagramm wird geladen…
Implementierung:
public class Raumschiff{ private String typ; private Pilot pil; // Referenz-Attribut public void setPilot(Pilot pp) { pil = pp; // Referenz wird gespeichert — nicht das Objekt kopiert! } public Pilot getPilot() { return pil; // Gibt die Referenz zurück — Zugriff auf das Original }}
Hinweis
Rollenverteilung:WeltraumSim erzeugt alle Objekte (new). Raumschiff erzeugt den Piloten nicht selbst — es bekommt nur die Referenz zugewiesen. So kann der Pilot gewechselt werden.
Reflexionsfrage: Warum erzeugt das Raumschiff den Piloten nicht selbst im Konstruktor (z.B. pil = new Pilot();)? Wann wäre das sinnvoll, wann nicht?
Was passiert bei setPilot(p1) im Speicher?
p1 enthält die Adresse des Pilot-Objekts (z.B. 0x500).
setPilot(p1) übergibt diese Adresse an den Parameter pp.
pil = pp kopiert die Adresse nach pil.
Ergebnis: p1 (in WeltraumSim) und pil (in Raumschiff) speichern beide 0x500 — dasselbe Objekt.
Mermaid-Diagramm
Mermaid-Diagramm wird geladen…
Tipp
Erkläre, bevor du weiterliest: Was genau passiert im Speicher, wenn setPilot(p1) aufgerufen wird? Wird der Pilot kopiert? Schreibe 2–3 Sätze auf.
Probiere es selbst aus:
IDE lädt…
Sicherheit: null-Check vor dem Zugriff
getPilot() kann null zurückgeben — wenn noch kein Pilot zugewiesen wurde.
Pilot p = rs1.getPilot();if (p != null){ System.out.println(p.getName());}
Wichtig
Ohne null-Check: rs1.getPilot().getName() → NullPointerException, wenn kein Pilot gesetzt ist.
Ruhige Sicherung: Referenz, Adresse, Objekt
Tipp
Ordne die drei Ebenen sauber:
Ebene
Frage
Beispiel
Variable
Wo steht die Referenz?
rs1
Referenzwert
Welche Adresse wird gespeichert?
0x1A4F
Objekt
Was liegt an dieser Adresse?
Raumschiff(groesse=100)
Der häufigste Denkfehler ist, Variable und Objekt gleichzusetzen. Die Variable ist nicht das Objekt. Sie enthält nur die Adresse, über die das Objekt gefunden wird.
a) Ändert wechslePilot(meins) den Piloten im Original-Raumschiff meins? Begründe.
b) Ändert resetSchiff(meins) das Original-Raumschiff? Begründe.
c) Erkläre den Unterschied mit dem Satz: „Java übergibt eine Kopie der ___."
Teste deine Vermutung:
IDE lädt…
Textabgabe
A5: Sichere Getter (Vertiefung)
getPilot() gibt eine Referenz auf das Original-Pilot-Objekt zurück. Das bedeutet: Jeder, der getPilot() aufruft, kann den Piloten im Raumschiff verändern — auch unbeabsichtigt.
a) Ist das gefährlich? Nenne ein Szenario, in dem das zum Problem wird.
b) Schreibe eine „sichere" Version getPilotKopie(), die eine Kopie des Piloten zurückgibt. Tipp: Du brauchst new Pilot(pil.getName()).
c) Wann lohnt sich der Aufwand einer Kopie, wann nicht?
Textabgabe
Phase 4: Transfer und Vernetzung
Transferaufgabe
Durchgängiges Projekt: Online-Shop
Diese Aufgabe ist Teil des Online-Shop-Projekts, das sich durch den Kurs Lineare Datenstrukturen 1 zieht. In Kapitel 01 hast du Produkt und Kunde kennengelernt. Jetzt kommt der Warenkorb dazu.
Projektstand Online-Shop
Der Shop kann jetzt Beziehungen speichern: Ein Warenkorb, ein Kunde oder ein Produkt kann eine Referenz auf ein anderes Objekt halten. Damit wird aus einzelnen Klassen ein kleines Objektsystem.
Die Grenze ist aber noch sichtbar: Für viele Produkte reicht eine einzelne Referenz nicht mehr aus.
Online-Shop: Warenkorb
Entwirf eine Klasse Warenkorb mit einer Referenz aktuellesProdukt auf ein Produkt.
a) Zeichne ein Klassendiagramm.
b) Implementiere setAktuellesProdukt(Produkt p) und getAktuellesProdukt().
c) Schreibe eine Methode wechsleProdukt(Produkt neues). Was passiert mit dem alten Produkt-Objekt — wird es gelöscht?
IDE lädt…
Projekt: Bank-Software
Projekt: Bank-Software (umfangreich)
Entwirf und implementiere eine vereinfachte Bank-Software mit 4 Klassen:
Mermaid-Diagramm
Mermaid-Diagramm wird geladen…
Aufgaben:
a) Implementiere die Klassen Konto, Depot und Kunde.
b) Implementiere anfangsWerte() in Bank: Erzeuge 2 Kunden, 2 Konten, 1 Depot. Weise jedem Kunden ein Konto zu. Nur Kunde 1 bekommt ein Depot.
c) Implementiere kontoBearbeiten(Kunde pk): Zeige den Kontostand an, lass einzahlen oder abheben.
d) Implementiere depotBearbeiten(Kunde pk): Prüfe zuerst mit hatDepot(), ob der Kunde ein Depot hat. Wenn ja: Aktie anzeigen, kaufen/verkaufen. Wenn nein: Meldung ausgeben.
e) Reflexionsfrage: Was passiert, wenn zwei Kunden dasselbe Konto-Objekt zugewiesen bekommen? Erkläre mit Aliasing.
IDE lädt…
Vernetzung
Heute gelöst: Der Pfeil aus Kapitel 01 ist jetzt kein bloßes Bild mehr. Du weißt: Eine Referenz ist ein Adresswert. Bei einer Übergabe an eine Methode wird diese Adresse kopiert. Das Originalobjekt kann dadurch verändert werden, aber die ursprüngliche Variable wird nicht einfach umgebogen.
Noch offen: Bisher haben wir einzelne Referenzen betrachtet: ein Raumschiff kennt einen Piloten, ein Kunde kennt ein Lieblingsprodukt. Reale Systeme brauchen aber nicht nur einen Pfeil, sondern viele Pfeile nebeneinander.
Nächster Schritt: Im nächsten Kapitel entstehen Arrays von Referenzen. Die neue Falle: Viele Plätze bedeuten noch nicht viele Objekte.
Reflexion
Hinweis
Beantworte die Leitfrage:
Wie sieht eine Referenz im Speicher aus? Was passiert, wenn du sie an eine Methode weitergibst?
Nutze die Begriffe „Adresse", „Kopie der Referenz" und „Original-Objekt".
Textabgabe
Selbstdiagnose
Ich kann erklären, was eine Referenz im Speicher ist (eine Adresse).
Ich kann ein Speicherabbild zu gegebenem Code zeichnen (Adresse | Daten | Interpretation).
Ich kann Setter/Getter für Referenz-Attribute schreiben.
Ich weiß, wann ich einen null-Check brauche.
Ich kann erklären, ob eine Methode das Original-Objekt verändert oder nicht.