Alle Tabs der Lerneinheit (Erklärung · Interaktiv · Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).
Erklärung
Eine Variable ist ein Name, über den ein Wert bzw. ein Objekt erreichbar ist. Bei Java-Primitiven steht der Wert direkt in der Variable; bei Java-Objekten enthält die Variable eine Referenz auf das Objekt. In Python bindet ein Name an ein Objekt, das Objekt hat den Typ, nicht der Name. Du lernst hier, welche Grundtypen (int, double, boolean, String/char) du in Klausuren sicher beherrschen musst, welcher Wertebereich für welchen Typ gilt, wann eine Konvertierung (Widening vs Narrowing, expliziter Cast) erlaubt ist und worin sich primitive Datentypen von Referenz-Typen unterscheiden. Das ist Pflichtstoff im 1. Semester Informatik, Wirtschaftsinformatik und allen verwandten Studiengängen.
Bevor wir ins Beispiel gehen, eine zentrale Unterscheidung: Primitive Typen speichern Werte direkt (die 21 liegt im Speicherbereich der Variable selbst), Referenz-Typen speichern eine Referenz auf ein Objekt (eine Art "Verweis", der zur Laufzeit von der JVM auf eine Speicheradresse aufgelöst wird; das Objekt selbst lebt woanders im Heap). Diese Unterscheidung erklärt, warum z.B. == bei Strings unzuverlässig ist und warum final nicht gleich "unveränderlich" bedeutet.
Mini-Beispiel, das die ganze Logik in vier Zeilen zeigt:
int alter = 21; // Java: Typ vorne, Wert (21) liegt direkt im Speicher
String name = "Anna"; // Java: String ist KEIN primitiver Typ -> Variable hält Referenz aufs Objekt
Eine Variable ist im Grunde ein Container mit einem Namen (dem Identifier), durch den du auf einen Wert zugreifen kannst. Vier Dinge stecken in dieser Mini-Szene drin:
- Name:
alterbzw.name(was du im Code schreibst, der Identifier der Variable) - Typ:
int(primitiver Typ, 32-bit) bzw.String(Klasse) - Wert: 21 bzw.
"Anna" - Speicher-Form: bei
intsteht die 21 direkt in der Variable. BeiStringenthältnamenur eine Referenz, das eigentliche Anna-Objekt liegt im Heap.
Eine spätere Zuweisung alter = 22; ersetzt den Wert. Ein name = "Ben"; lässt das Anna-Objekt unangetastet und biegt die Referenz auf ein neues String-Objekt um.
alter ─►┌────┐ name ─►┌─ref─┐ ┌────────────┐
│ 21 │ │ *──┼────────►│ "Anna" │
└────┘ └─────┘ └────────────┘
Primitive: Wert liegt Reference: Variable hält Adresse,
direkt in der Variable Objekt liegt im Heap
Die wichtigsten Datentypen, die du in der Klausur kennen musst:
- int: Ganzzahl, z.B. 42 oder -7. In Java 32-bit (Wertebereich
-2^(31)bis2^(31)-1). Für größere ganze Zahlen:long(64-bit). Weitere primitive Integer-Typen:byte(8-bit),short(16-bit). - float / double: Kommazahlen. Java-Standard ist
double(64-bit Gleitkomma).floatist nur 32-bit, weniger genau, und Java-Literale wie3.14sind standardmäßigdouble. Fürfloatmuss man3.14fschreiben oder einen expliziten Cast (englisch explicit cast, schreibt den Ziel-Typ in Klammern vor den Wert, z.B.(float) 3.14) verwenden. - boolean: Wahrheitswert, true oder false
- char (Java): einzelner 16-bit UTF-16-Code-Unit, z.B.
'a'(mit einfachen Anführungszeichen) - String: Zeichenkette, z.B. "Hallo" (Anführungszeichen)
Java ist statisch typisiert: Typ wird beim Deklarieren festgelegt und bleibt fest. Python ist dynamisch typisiert: der Name wird zur Laufzeit an ein Objekt gebunden, und derselbe Name kann später an ein Objekt mit anderem Typ gebunden werden. In der Klausur wirst du oft gefragt: welcher Typ passt für welchen Wert? und kann ich diesen Wert in jenen Typ konvertieren ohne Datenverlust?
Deklaration
In Java muss jede Variable einen Typ haben, in Python wird der Typ automatisch erkannt.
int alter = 21;
String name = "Anna";
double note = 1.7;
boolean bestanden = true;Java: Typ steht vorne, dann der Name, dann der Wert.
alter = 21
name = "Anna"
note = 1.7
bestanden = TruePython ist dynamisch typisiert: Der Name wird zur Laufzeit an ein Objekt gebunden, und das Objekt hat einen Typ. Derselbe Name kann später an ein Objekt mit anderem Typ gebunden werden.
Wichtige Datentypen
| Typ | Beispiel | Wofür |
|---|---|---|
| int (Java 32-bit) / int (Python beliebig groß) | 42 | Ganze Zahlen |
| double (Java-Standard, 64-bit) | 3.14 | Kommazahlen, Standardwahl |
| float (Java 32-bit, weniger genau) | 3.14f | Kommazahlen, sparsamer |
| String / str | "Hallo" | Text |
| boolean / bool | true / false / True / False | Wahrheitswerte |
Weitere Java-Primitive:
byte(8-bit),short(16-bit),long(64-bit, Literal mitL-Suffix),char(16-bit UTF-16).
Faustregel zur Typ-Wahl: Für ganze Zahlen nutze fast immer int. Nur bei extrem großen Zahlen (über 2 Mrd.) wähle long. byte und short sind Spezialkandidaten für hardware-nahe oder speicher-kritische Situationen (Embedded-Systeme, große Datenmengen mit fester Bit-Breite), kommen in Standard-BWL/Info-Klausuren selten vor. char brauchst du nur wenn du wirklich genau ein Zeichen meinst, sonst lieber String.
Konvertierungen: Widening vs Narrowing
WIDENING (implizit erlaubt, KEINE Compile-Errors):
byte → short → int → long → float → double
(1) (2) (3)
(1) auch char → int direkt erlaubt
(2) int → float: Präzisionsverlust möglich (float-Mantisse 24 Bit
effektiv, int hat 32 Bit Nutzdaten). int → double ist dagegen
VERLUSTFREI (double-Mantisse 53 Bit effektiv reicht für jeden int).
(3) long → float und long → double: Präzisionsverlust möglich
(long hat 64 Bit, double-Mantisse nur 53 Bit effektiv)
NARROWING (expliziter Cast nötig, Datenverlust möglich):
double → float → long → int → short → byte
Beispiel: int x = (int) 3.7; // Ergebnis: 3 (Truncation, kein Runden)
Welche Widening-Konvertierungen sind verlustfrei, welche nicht?
| Konvertierung | Verlustfrei? | Grund |
|---|---|---|
byte → int | ✅ ja | int (32 Bit) deckt byte-Wertebereich komplett ab |
int → long | ✅ ja | long (64 Bit) deckt int komplett ab |
int → double | ✅ ja | double-Mantisse (53 Bit effektiv) reicht für jeden int |
float → double | ✅ ja | double ist eine Obermenge von float |
int → float | ⚠️ kann verlieren | float-Mantisse (24 Bit effektiv) zu klein für große int |
long → float | ⚠️ kann verlieren | gleiche Logik, noch dramatischer |
long → double | ⚠️ kann verlieren | double-Mantisse (53 Bit) zu klein für große long (64 Bit) |
Java erlaubt diese Konvertierungen alle implizit OHNE Cast (kein Compile-Error), aber bei den ⚠️-Fällen bekommst du eine gerundete Approximation statt des exakten Werts. Hinweis zur Mantisse: IEEE-754 nutzt einen impliziten führenden 1-Bit, also 23 gespeicherte + 1 implizit = 24 effektive Mantissen-Bits bei float bzw. 52 + 1 = 53 bei double.
Normale Variablen können neu zugewiesen werden. Ausnahmen:
- Java
final:final int x = 5;,xkann nicht neu zugewiesen werden. - Mutability vs. Reassignment: Auch ohne
finalmuss man unterscheiden zwischen "den Namen auf ein anderes Objekt zeigen lassen" (Reassignment) und "das Objekt selbst verändern" (Mutation). In Python sindint,str,tuplez. B. unveränderlich (immutable), aber der Name kann an ein neues Objekt gebunden werden.
In statisch typisierten Sprachen wie Java bleibt der Typ einer Variable fest: aus einem int wird kein String. In dynamisch typisierten Sprachen wie Python kannst du denselben Namen später für einen anderen Typ wiederverwenden, was Flexibilität gibt, aber auch Fehlerquellen.
Interaktiv
Variable selbst ausprobieren
Wähle einen Typ, gib einen Wert ein und schau wie Java reagiert. Probier auch Python, dort wird der Typ automatisch erkannt.
Interaktive Visualisierung
Schritt-für-Schritt-Trace, wie sich Variablen-Werte im Speicher verändern.
Tipp: Versuch mal in Java den Typ int und gib 3.14 ein. Java akzeptiert das nicht (kein Integer). In Python klappt das problemlos: x ist nicht vorher als int festgelegt, x = 3.14 bindet den Namen x an ein neues float-Objekt. In Python wird x also nicht zu einem int mit Dezimalstellen (das gibt es nicht), sondern zeigt danach einfach auf ein anderes Objekt mit anderem Typ.
Code-Stepper: Schritt für Schritt durchspielen
Vier interaktive Demos zu den klassischen Klausur-Themen rund um Datentypen: Int-Overflow, Cast widening/narrowing, Primitive vs Reference im Speicher, und Pythons dynamische Typisierung. Klick Step oder Auto und beobachte, wie sich Variablen verändern.
1. Int-Overflow: warum 1_500_000_000 × 2 negativ wird
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
2. Cast: int → double → int (Widening + Narrowing)
Widening (implizit erlaubt ohne Cast) vs. Narrowing (expliziter Cast nötig, Datenverlust möglich). Beobachte den pi-Truncation-Schritt.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
3. Primitive vs Reference: Wert kopieren vs Adresse kopieren
Klassiker: y = x mit primitiven Werten kopiert den Wert. b = a mit String-Referenzen kopiert die Adresse, beide zeigen aufs selbe Objekt, bis man eine Referenz umbiegt.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
4. Python dynamic typing: derselbe Name, drei verschiedene Typen
In Python gehört der Typ zum Objekt, nicht zum Namen. Du kannst denselben Namen über die Zeit an Objekte unterschiedlicher Typen binden.
Interaktive Visualisierung
Interaktive Komponente: probiere sie im Topic-Player oben aus.
Quiz
Klausurfragen mit Lösungen (7)
- F1.Welcher Datentyp speichert in Java das Literal 3.14 direkt korrekt?
Antwort: double
Erklärung: In Java ist `3.14` **standardmäßig ein double-Literal**, `double note = 3.14;` ist korrekt. Für `float` muss man explizit `3.14f` schreiben oder casten, sonst Compile-Fehler. `int` kann nur ganze Zahlen, `boolean` nur Wahrheitswerte. Java-`double` ist 64-bit (Standardwahl), `float` nur 32-bit (weniger genau).
- F2.Eine Variable wurde als ganze Zahl deklariert. Welche Zuweisung wäre in Java problematisch?
Antwort: alter zu einem String machen
Erklärung: In Java ist der Typ fest: aus einem int kann kein String werden. In Python wäre das technisch erlaubt, aber konzeptuell falsch wenn alter ein Alter darstellen soll.
- F3.Welche der folgenden sind primitive Datentypen in Java?
Richtige Antworten: int; double; boolean
Erklärung: int, double und boolean sind primitive Datentypen, der Wert steht direkt in der Variable. String und ArrayList sind Klassen: **Variablen vom Typ String / ArrayList sind Referenzvariablen**, sie enthalten eine Referenz auf ein Objekt im Heap, nicht den Objektinhalt wie ein primitiver Wert. Klausur-Klassiker zur Unterscheidung Primitive vs Reference Types.
Typ: Multi-Select
- F4.In Python kann derselbe Name zur Laufzeit erst an ein int-Objekt und später an ein str-Objekt gebunden werden.
Antwort: Wahr
Erklärung: Genau so funktioniert dynamische Typisierung in Python: der **Name** hat keinen Typ, das **Objekt** hat den Typ. `x = 5` bindet den Namen `x` an ein int-Objekt, ein späteres `x = "Hallo"` bindet denselben Namen an ein str-Objekt um, das int-Objekt wird (wenn nichts mehr darauf zeigt) per Garbage Collection eingesammelt. In Java geht das NICHT, der Typ ist Teil der Variable und steht fest beim Deklarieren.
Typ: Wahr/Falsch
- F5.Wie viele Bits hat ein int in Java auf jeder Plattform?
Antwort: 32 Bit
Erklärung: Java's `int` ist immer 32 Bit (4 Byte), unabhängig von der Plattform, anders als in C, wo die Größe variieren kann. Wertebereich: `-2^(31)` bis `2^(31)-1`, also etwa -2,1 Mrd. bis +2,1 Mrd.
Typ: Zahlen-Eingabe
- F6.Was passiert in Java bei int x = 3.14;?
Antwort: Compile-Fehler
Erklärung: Java erlaubt KEINE implizite Umwandlung von double zu int (potenzieller Datenverlust). Compile-Fehler. Mit explizitem Cast `int x = (int) 3.14;` würde x = 3 ergeben (Truncation, kein Runden).
- F7.Tracing-Aufgabe (Java): Welcher Wert steht am Ende in result?
Antwort: -1294967296
Erklärung: Klausur-Klassiker mit zwei Stolperstellen: 1. **Int-Overflow vor dem Cast:** `a * b` rechnet als `int * int = int`. 1_500_000_000 × 2 = 3_000_000_000, das passt nicht in `int` (max ist `2^(31)-1` = 2_147_483_647). Java wirft KEINE Exception, sondern macht still einen Overflow modulo `2^(32)`. Bit-Pattern: 3_000_000_000 = 0xB2D05E00, höchstes Bit gesetzt → als signed int interpretiert ergibt das **-1_294_967_296** (= 3_000_000_000 − 4_294_967_296). 2. **Erst dann `(double)`-Konversion + `(int)`-Cast zurück:** Die schon kaputte int-Zahl wird verlustfrei zu double promoted (`-1.294...e9`), dann zurück zu int gecastet ohne weiteren Datenverlust. End-Resultat: **-1294967296**. **Lehre:** Bei großen Multiplikationen IMMER vorher zu `long` casten: `long c = (long) a * b;` oder Literal `1_500_000_000L`. In Python passiert das nicht, weil `int` dort beliebig groß ist.
Typ: Zahlen-Eingabe
int alter = 21;
// Welche dieser Zuweisungen ist NICHT erlaubt?int a = 1_500_000_000;
int b = 2;
double c = a * b;
int result = (int) c;