W3docs

Java String-Konvertierungen

Konvertierung zwischen Java-Strings und primitiven Typen — Integer.parseInt, Double.parseDouble, String.valueOf und mehr.

Die meisten Daten kommen als Text an und verlassen das System als Text. Dazwischen leben sie meist in einer nützlicheren Form — als int, double, boolean oder LocalDate. Dieses Kapitel behandelt die beiden Konvertierungsrichtungen zwischen String und primitiven Typen, Wrapper-Typen sowie Zeichen-Arrays.

Es gibt ein kleines Vokabular, das es sich lohnt zu lernen; sobald man es kennt, ist die Antwort auf „Wie wandle ich diesen String in ein X um?" jedes Mal eine einzeilige Lösung.

String → Primitiv: die parse...-Familie

Jede Wrapper-Klasse hat eine statische Methode, die einen String entgegennimmt und den entsprechenden primitiven Typ zurückgibt:

int    i = Integer.parseInt("42");
long   l = Long.parseLong("9999999999");
double d = Double.parseDouble("3.14");
float  f = Float.parseFloat("3.14");
short  s = Short.parseShort("32000");
byte   b = Byte.parseByte("127");
boolean ok = Boolean.parseBoolean("true");  // any case-insensitive "true"; everything else → false

Das sind die Standardwerkzeuge. Sie werfen eine NumberFormatException bei Eingaben, die sich nicht parsen lassen — einschließlich null, leerer Strings, Strings mit führenden oder abschließenden Leerzeichen, gebietsschemaspezifischer Dezimalzahlen wie "3,14" und Werten außerhalb des erlaubten Bereichs.

Integer.parseInt(" 42 ");      // NumberFormatException — trim first
Integer.parseInt("3.0");       // NumberFormatException — that's a double
Integer.parseInt("1234567890123"); // NumberFormatException — overflows int

Integer.parseInt akzeptiert ein optionales zweites Argument für die Basis (Radix):

Integer.parseInt("ff", 16);    // 255
Integer.parseInt("1010", 2);   // 10
Integer.parseInt("777", 8);    // 511 — the radix is the second arg, not a prefix
Integer.parseInt("0x1A", 16);  // NumberFormatException — no "0x" prefix; pass just "1A"

parseInt liest die buchstäblichen Ziffern in der angegebenen Basis; Quellcode-Präfixe wie 0x oder eine führende 0 für Oktal werden nicht verstanden. Integer.parseInt("0777", 8) ist also in Ordnung — die führende 0 ist lediglich eine weitere Oktalziffer — aber Integer.parseInt("0x1A", 16) wirft eine Ausnahme, weil x keine Basis-16-Ziffer ist. Entferne Präfixe selbst, bevor du parsst.

Für die vorzeichenlose Interpretation des höchsten Bits bei 32- und 64-Bit-Werten bietet das JDK Integer.parseUnsignedInt und Long.parseUnsignedLong.

String → Wrapper: valueOf vs. parse...

Das statische valueOf jeder Wrapper-Klasse führt dasselbe Parsen durch, gibt aber den Wrapper-Typ zurück:

Integer n = Integer.valueOf("42");     // Integer, not int
Double d  = Double.valueOf("3.14");    // Double, not double

Die beiden unterscheiden sich in drei Punkten, die gelegentlich relevant sind:

  • Rückgabetyp. parseIntint, valueOfInteger. Wähle je nachdem, was der Empfänger erwartet.
  • Caching. Integer.valueOf(int) und Long.valueOf(long) cachen kleine Zahlen (standardmäßig -128..127) und geben bei wiederholten Aufrufen dieselbe Integer-Instanz zurück. parseInt gibt einen Primitiv zurück, daher ist Caching irrelevant — aber wenn das Ergebnis ohnehin geboxt werden würde, ist valueOf günstiger.
  • Verhalten bei Überlauf. Identisch — beide werfen NumberFormatException.

Faustregel: Wenn du einen Primitiv willst, verwende parseInt; wenn du einen Wrapper willst, verwende valueOf. Schreibe nicht Integer.valueOf(Integer.parseInt(s)) — das ist doppelter Code für ein einmaliges Ergebnis.

Primitiv → String: String.valueOf und verwandte Methoden

Die umgekehrte Richtung hat zwei gut benannte Werkzeuge:

String s1 = String.valueOf(42);              // "42"
String s2 = String.valueOf(3.14);            // "3.14"
String s3 = String.valueOf(true);            // "true"
String s4 = String.valueOf('a');             // "a"
String s5 = String.valueOf(new char[]{'h','i'}); // "hi"
String s6 = String.valueOf((Object) null);   // "null"  — NOT an NPE

Jeder Wrapper hat auch eine toString-Methode, die den Primitiv entgegennimmt:

Integer.toString(42);          // "42"
Integer.toString(255, 16);     // "ff"   — radix overload
Long.toString(123456789L);     // "123456789"
Double.toString(3.14);         // "3.14"

Und natürlich funktioniert die Verkettung mit "":

String s = "" + 42;            // "42"

String.valueOf ist die allgemeinste und am besten vertretbare Variante — es wirft keine Ausnahme bei null und verarbeitet jeden Primitiv sowie Object. Für numerische Formatierungen, bei denen du Breite, Vorzeichen, Gruppierung oder gebietsschemaspezifische Dezimalzahlen benötigst, greife stattdessen auf String.format zurück.

Strings und Chars

Ein char ist ein Primitiv (eine UTF-16-Codeeinheit); ein String ist eine Folge davon. Konvertierungen in beide Richtungen:

String  s   = String.valueOf('a');       // "a"
char    c1  = "abc".charAt(0);           // 'a'
char[]  arr = "abc".toCharArray();       // ['a', 'b', 'c']
String  s2  = new String(arr);           // "abc"
String  s3  = new String(arr, 1, 2);     // "bc" — offset + count

String.toCharArray() gibt immer ein neues, änderbares Array zurück. Das ist das richtige Werkzeug, wenn Zeichen geändert werden müssen (z. B. um einen Passwort-Puffer zu löschen) — String selbst kann keine änderbare Ansicht liefern.

Strings und Bytes

Bytes sind das Übertragungsformat; Strings sind die In-Memory-Form. Die Konvertierung erfordert immer einen Zeichensatz, und die richtige Antwort lautet immer, ihn explizit anzugeben:

byte[] bytes = "héllo".getBytes(StandardCharsets.UTF_8);
String back  = new String(bytes, StandardCharsets.UTF_8);

Die Überladungen ohne Argumente (getBytes(), new String(bytes)) verwenden den Standard-Zeichensatz der JVM, der plattformabhängig ist und eine häufige Quelle für „läuft bei mir"-Fehler darstellt. Übergebe immer einen Charset. UTF-8 ist der richtige Standard für neuen Code; Legacy-Systeme benötigen manchmal Latin-1 oder eine der Windows-Codepages.

Konvertierungen, die nicht existieren

Einige Konvertierungen, nach denen Entwickler greifen, die es aber nicht gibt:

  • intchar nach Ziffernwert. (char) 5 ist das Steuerzeichen an Codepoint 5, nicht '5'. Verwende Character.forDigit(5, 10) oder (char) ('0' + 5).
  • charint nach Ziffernwert. (int) '5' ist 53, nicht 5. Verwende Character.digit('5', 10) oder '5' - '0'.
  • String → numerisch mit Standardwert bei Fehler. Java liefert kein parseIntOrDefault. Die idiomatische Version ist ein kleiner Helfer:
static int parseIntOr(String s, int fallback) {
  try { return Integer.parseInt(s); }
  catch (NumberFormatException e) { return fallback; }
}

Konvertierung ist keine Validierung

Der größte Fehler bei der String-zu-Primitiv-Konvertierung ist, eine erfolgreiche Konvertierung als erfolgreiche Validierung zu behandeln. Integer.parseInt("0") gibt 0 für jede Eingabe zurück, die der Benutzer als Null eingibt, einschließlich "0", "00", "+0" und "-0" — all diese parsen zum selben Wert. Wenn du wissen willst, ob die Eingabe kanonisch war, parse und konvertiere dann zurück:

int v = Integer.parseInt(input);
if (!Integer.toString(v).equals(input)) {
  throw new IllegalArgumentException("non-canonical integer: " + input);
}

Bei numerischen Eingaben aus benutzerorientierten Formularen solltest du zuerst das Format validieren (Regex, Länge, erlaubte Zeichen) und dann parsen. Verlasse dich nicht darauf, dass der Parser dir sagt, ob die Eingabe sinnvoll war.

Ein ausgearbeitetes Beispiel

Ein Programm, das in beiden Richtungen über die häufigsten Typen konvertiert, einschließlich eines robusten Standardwert-bei-Fehler-Helfers, eines Hex-Roundtrips und eines Byte/String-Roundtrips mit UTF-8.

java— editable, runs on the server

Drei Details fallen in der Ausgabe auf. Der héllo-String wird sauber über UTF-8 hin- und zurückkonvertiert — fünf Zeichen werden zu sechs Bytes (das é belegt zwei), und die resultierenden Bytes lassen sich wieder zu denselben fünf Zeichen parsen. String.valueOf((Object)null) erzeugt "null" anstatt eine Ausnahme zu werfen — das ist beabsichtigt; genau deshalb löst "x = " + nullable keine Ausnahme aus. Und der parseIntOr-Helfer verarbeitet fehlerhafte, mit Leerzeichen gefüllte und null-Eingaben, ohne dass die aufrufende Stelle davon wissen muss.

Was kommt als nächstes

Das abschließende Kapitel von Teil 9 behandelt die beiden meistgenutzten Methoden „String rein, Liste raus / Liste rein, String raus" aus der Standardbibliothek — sowie die Regex-Varianten, die darunter liegen. Weiter zu Java String split() und join().

Übungen

Übung
Was ist der Unterschied zwischen `Integer.parseInt('42')` und `Integer.valueOf('42')`?
Was ist der Unterschied zwischen `Integer.parseInt('42')` und `Integer.valueOf('42')`?
Was this page helpful?