Java-Datentypen
Entdecke Javas primitive Datentypen (byte, short, int, long, float, double, char, boolean) und Referenztypen.
Java ist statisch typisiert — jede Variable hat einen Typ, der zur Kompilierzeit bekannt ist. Typen fallen in zwei Kategorien: Primitive (rohe Werte, die in die Sprache eingebaut sind) und Referenztypen (Objekte, Arrays, alles, was mit new erstellt wird). Dieses Kapitel behandelt beide.
Die acht primitiven Typen
Primitive sind die einzigen Werte in Java, die keine Objekte sind. Sie speichern ihren Wert direkt im Speicherplatz der Variable. Java definiert genau acht:
| Typ | Größe | Wertebereich | Standardwert | Beispiel-Literal |
|---|---|---|---|---|
byte | 8 Bits | -128 bis 127 | 0 | byte b = 100; |
short | 16 Bits | -32.768 bis 32.767 | 0 | short s = 30000; |
int | 32 Bits | -2³¹ bis 2³¹-1 (≈ ±2,1 Milliarden) | 0 | int i = 1_000_000; |
long | 64 Bits | -2⁶³ bis 2⁶³-1 | 0L | long l = 9_000L; |
float | 32 Bits | IEEE 754 einfache Genauigkeit | 0.0f | float f = 3.14f; |
double | 64 Bits | IEEE 754 doppelte Genauigkeit | 0.0 | double d = 3.14; |
char | 16 Bits | Unicode-Codeeinheit (U+0000 bis U+FFFF) | \0 | char c = 'A'; |
boolean | JVM-definiert | true oder false | false | boolean b = true; |
Ein paar Dinge, die man sich merken sollte:
intist der Standard-Ganzzahltyp. Die meisten Zähler und Indizes sindint. Verwendelongnur dann, wenn du tatsächlich Zahlen über ~2 Milliarden benötigst.doubleist der Standard-Gleitkommatyp. Das schlichte3.14ist eindouble;3.14fist einfloat. Verwendedouble, es sei denn, der Speicherdruck erzwingtfloat.- Unterstriche in numerischen Literalen verbessern die Lesbarkeit:
1_000_000ist dasselbe wie1000000. - Standardwerte gelten nur für Felder, nicht für lokale Variablen. Eine lokale Variable hat keinen Standardwert — du musst sie initialisieren, bevor du sie liest.
Referenztypen
Alles andere — String, Arrays, deine eigenen Klassen, Bibliotheksklassen — ist ein Referenztyp. Eine Referenztyp-Variable hält nicht das Objekt selbst; sie hält eine Referenz (im Wesentlichen einen Zeiger) auf das Objekt im Heap:
String name = "Ada";
int[] scores = new int[10];
LocalDate today = LocalDate.now();Der Standardwert jeder Referenzvariable ist null — ein spezieller Wert, der „kein Objekt" bedeutet.
String s = null;
System.out.println(s.length()); // throws NullPointerException at runtimenull ist die Ursache eines der häufigsten Laufzeitfehler in Java. Das Kapitel Java Exceptions erklärt, wie man die dabei entstehende NullPointerException behandelt.
Wrapper-Klassen
Jeder primitive Typ hat eine passende Wrapper-Klasse — ein echtes Objekt, das den primitiven Wert kapselt:
| Primitiv | Wrapper |
|---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
Wrapper werden benötigt, wenn du primitive Werte in Collections einfügen möchtest (die nur Objekte aufnehmen):
List<Integer> scores = new ArrayList<>();
scores.add(42); // autoboxed from int → Integer
int first = scores.get(0); // unboxed from Integer → intJava wandelt automatisch zwischen Primitiven und Wrappern um — dies wird als Autoboxing und Unboxing bezeichnet — sodass man es meistens gar nicht bemerkt.
Hinweis zu String
String ist ein Referenztyp, kein Primitiv. Er ist besonders genug, dass ihm die Sprache eine Literalsyntax ("text") und den +-Operator gibt. Strings sind unveränderlich — einmal erstellt, ändern sich ihre Inhalte nie. Jede „Änderung" gibt einen neuen String zurück. Das Kapitel Java Strings geht tiefer darauf ein.
Einen Typ wählen
Ein kurzer Entscheidungsbaum für den Java-Alltag:
- Dinge zählen oder Array-Indizes →
int - Große Zahlen (Dateigrößen, Zeitstempel in Millisekunden) →
long - Geldbeträge →
BigDecimal(nichtdouble— Gleitkomma-Rundung wird dich erwischen) - Einzelnes Zeichen →
char - Ja/Nein →
boolean - Text →
String - Datum oder Uhrzeit → Typen in
java.time(LocalDate,Instant,Duration)
Widerstehe dem Drang, durch die Verwendung von byte oder short für gewöhnliche Ganzzahlen „Speicher zu sparen". JVMs sind auf int-Operationen optimiert; short verbraucht in den meisten Fällen tatsächlich nicht weniger Speicher.
Häufige Fallstricke
Einige Typenverhalten überraschen Einsteiger regelmäßig. Diese im Voraus zu kennen spart Stunden beim Debuggen.
Integer-Überlauf geschieht lautlos
Ganzzahlarithmetik in Java wirft bei einem Überlauf nie eine Ausnahme — sie läuft um. Das Addieren von 1 zum größten int ergibt den kleinsten int:
int max = Integer.MAX_VALUE; // 2147483647
System.out.println(max + 1); // -2147483648Wenn ein Wert ~2,1 Milliarden überschreiten könnte, verwende long. Für Zahlen, die sogar long überlaufen könnten, greife auf BigInteger zurück.
Gleitkommazahlen sind nicht exakt
float und double folgen dem IEEE 754-Standard, der die meisten Dezimalbrüche nicht exakt darstellen kann. Das klassische Beispiel:
System.out.println(0.1 + 0.2); // 0.30000000000000004Deshalb solltest du double niemals für Geldbeträge verwenden. Verwende BigDecimal (aus einem String konstruiert, z. B. new BigDecimal("0.1")), wenn exakte Dezimalwerte wichtig sind.
char ist eine Zahl
Ein char ist eine vorzeichenlose 16-Bit-Ganzzahl, die eine Unicode-Codeeinheit enthält, und nimmt daher an Arithmetik teil:
char a = 'A';
System.out.println((int) a); // 65
System.out.println((char) (a + 1)); // BWrapper mit .equals() vergleichen, nicht mit ==
== bei Wrapper-Objekten vergleicht Referenzen, keine Werte. Aufgrund eines Autoboxing-Caches für kleine Integer-Werte (-128 bis 127) scheint == bei kleinen Zahlen zu funktionieren, schlägt aber bei großen fehl:
Integer a = 127, b = 127;
System.out.println(a == b); // true (cached)
Integer c = 128, d = 128;
System.out.println(c == d); // false (different objects)
System.out.println(c.equals(d)); // true (compares values)Verwende immer .equals() zum Vergleichen von Wrapper-Werten. Siehe Java Type Casting für die Regeln zur Konvertierung zwischen diesen Typen.
Eine funktionierende Demonstration
Wie geht es weiter
Java Type Casting zeigt, wie man zwischen numerischen Typen und zwischen verwandten Referenztypen konvertiert.