4.9 Formatieren von Ausgaben 

Immer wieder müssen Zahlen, Datumsangaben und Text auf verschiedenste Art und Weise formatiert werden. Zur Formatierung bietet Java zwei Lösungen:
- Seit Java 5 realisieren die format()- und printf()-Methoden eine Ausgabe, so wie sie unter C mit printf() gesetzt wurde.
- Formatieren über Format-Klassen: Allgemeines Formatierungsverhalten wird in einer ab-strakten Klasse Format fixiert; konkrete Unterklassen wie NumberFormat und DateFormat nehmen sich spezielle Datenformate vor.
- Die Format-Klassen bieten nicht nur landes- bzw. sprachabhängige Ausgaben per format(), sondern auch den umgekehrten Weg, Zeichenketten wieder in Typen wie double oder Date zu zerlegen. Jede Zeichenkette, die vom Format-Objekt erzeugt wurde, kann auch mit dem Parser wieder eingelesen werden.
4.9.1 Formatieren mit format() aus String 

Die Klasse String stellt mit der statischen Funktion format() eine Möglichkeit bereit, Zeichenketten nach einer Vorgabe zu formatieren.
String[] arg = { "Ulli", "Tina" };
String s = String.format( "Hallo %s. Es gab einen Anruf von %s.", arg );
System.out.println( s ); // Hallo Ulli. Es gab einen Anruf von Tina.
Der erste übergebene String nennt sich Format-String. Er enthält neben auszugebenden Zeichen weitere so genannte Format-Spezifizierer, die dem Formatierer darüber Auskunft geben, wie er das Argument formatieren soll. %s steht für eine unformatierte Ausgabe eines Strings.
%n |
neue Zeile |
%b |
Boolean |
%% |
Prozentzeichen |
%s |
String |
%c |
Unicode-Zeichen |
%d |
Dezimalzahl |
%x |
Hexadezimalschreibweise |
%t |
Datum und Zeit |
%f |
Fließkommazahl |
%e |
Wissenschaftliche Notation |
Variable Argumentlisten und System.out.printf()
Mit der Schreibweise von Java 5 für variable Argumentlisten ist das eigene arg-Feld nicht nötig, sodass sich der Funktionsaufruf vereinfacht zu:
String s = String.format( "Hallo %s. Es gab einen Anruf von %s.", "Ulli", "Tina" );
Praktischerweise ist das Formatieren und Ausgeben auch zu einer neuen Methode printf() in den PrintWriter und PrintStream (das System.out-Objekt ist vom Typ PrintStream) gewandert, sodass sich jetzt auch schreiben lässt:
System.out.printf( "Hallo %s. Es gab einen Anruf von %s.", "Ulli", "Tina" );
Auch bei printf() ist als erstes Argument ein Locale möglich.
final class java.lang.String
implements CharSequence, Comparable<String>, Serializable |
- static String format( String format, Object... args )
Liefert einen formatierten String, der aus dem String und den Argumenten hervorgeht.
- static String format( Locale l, String format, Object... args )
Liefert einen formatierten String, der aus der gewünschten Sprache, dem String und Argumenten hervorgeht.
Intern werkeln java.util.Formatter (keine java.text.Format-Objekte), die sich auch direkt verwenden lassen; dort ist auch die Dokumentation festgemacht.
Format-Spezifizierer
Die Anzahl der Format-Spezifizierer ist so groß und ihre weitere Parametrisierung so vielfältig, dass ein Blick in die API-Dokumentation auf jeden Fall nötig ist. Die wichtigsten Spezifizierer sind:
- %n ergibt das/die Zeichen für den Zeilenvorschub, jeweils bezogen auf die aktuelle Plattform. Die Schreibweise ist einem harten \n vorzuziehen, da dies nicht das Zeilenvorschubzeichen der Plattform sein muss.
- %% liefert das Prozentzeichen selbst, wie auch \\ in einem String den Backslash ausmaskiert.
- %s liefert einen String, wobei null zur Ausgabe »null« führt. %S schreibt die Ausgabe groß.
- %b schreibt ein Boolean, und zwar den Wert »true« oder »false« im Fall des Typs Boolean. Die Ausgabe ist immer »false« bei null und »true« bei anderen Typen wie Integer, String. %B schreibt den String groß.
- %c schreibt ein Zeichen, wobei die Typen Character, Byte und Short erlaubt sind. %C schreibt das Zeichen in Großbuchstaben.
- Für die ganzzahligen numerischen Ausgaben mit %d (Dezimal), %x (Hexadezimal), %o (Oktal) sind Byte, Short, Integer, Long und BigInteger erlaubt – %X schreibt die hexadezimalen Buchstaben groß.
- Bei den Fließkommazahlen mit %f oder %e (%E), %g (%G), %a (%A) sind zusätzlich die Typen Float, Double und BigDecimal zulässig.
- Im Fall von Datumsangaben mit %t bzw. %T sind erlaubt: Long, Calendar und Date. %t benötigt zwingend ein Suffix.
- Den Hashcode schreibt %h bzw. %H. Beim Wert null ist auch das Ergebnis »null«.
Zusätzliche Flags, etwa für Längenangaben und die Anzahl an Nachkommastellen, sind möglich und werden im folgenden Beispiel gezeigt.
Listing 4.24 PrintfDemo.java, main()
PrintStream o = System.out; int i = 123; o.printf( "|%d| |%d|%n" , i, -i ); // |123| |-123| o.printf( "|%5d| |%5d|%n" , i, -i ); // | 123| | –123| o.printf( "|%-5d| |%-5d|%n" , i, -i ); // |123 | |-123 | o.printf( "|%+-5d| |%+-5d|%n" , i, -i ); // |+123 | |-123 | o.printf( "|%05d| |%05d|%n%n", i, -i ); // |00123| |-0123| o.printf( "|%X| |%x|%n", 0xabc, 0xabc ); // |ABC| |abc| o.printf( "|%04x| |%#x|%n%n", 0xabc, 0xabc ); // |0abc| |0xabc| double d = 12345.678; o.printf( "|%f| |%f|%n" , d, -d ); // |12345,678000| |-12345,678000| o.printf( "|%.2f| |%.2f|%n" , d, -d ); // |12345,68| |-12345,68| o.printf( "|%,10f| |%,10f|%n" , d, -d ); // |12.345,678000| |-12.345,678000| o.printf( "|%10.2f| |%10.2f|%n" , d, -d ); // | 12345,68| | –12345,68| o.printf( "|%010.2f| |%010.2f|%n",d, -d ); // |0012345,68| |-012345,68| String s = "Monsterbacke"; o.printf( "%n|%s|%n", s ); // |Monsterbacke| o.printf( "|%20s|%n", s ); // | Monsterbacke| o.printf( "|%-20s|%n", s ); // |Monsterbacke | o.printf( "|%7s|%n", s ); // |Monsterbacke| o.printf( "|%.7s|%n", s ); // |Monster| o.printf( "|%20.7s|%n", s ); // | Monster| Date t = new Date(); o.printf( "%tT%n", t ); // 11:01:39 o.printf( "%tD%n", t ); // 04/18/08 o.printf( "%1$te. %1$tb%n", t ); // 18. Apr
Eine Ausgabe wie »formatiere einen String rechtsbündig« ist also mit der Methode printf() einfach möglich. Im Fall von Fließkommazahlen werden diese nach dem Modus BigDecimal.ROUND_HALF_UP gerundet, sodass etwa System.out.printf("%.1f", 0.45); die Ausgabe 0,5 ergibt.
4.9.2 Die Format-Klassen im Überblick 

DateFormat, MessageFormat und NumberFormat erweitern die abstrakte Klasse Format. Die Unterklassen übernehmen die Ein-/Ausgabe für Datumsangaben, für allgemeine Programmmeldungen und für Zahlen.
Das folgende Beispiel zeigt Anwendungen der Klassen.
Ergebnis | Formatiert mit |
02.09.2005 |
DateFormat.getDateInstance().format( new Date() ) |
15:25:16 |
DateFormat.getTimeInstance().format( new Date() ) |
02.09.2005 15:25:16 |
DateFormat.getDateTimeInstance().format( new Date() ) |
12.345,679 |
NumberFormat.getInstance().format( 12345.6789 ) |
12.345,68 € |
NumberFormat.getCurrencyInstance().format( 12345.6789 ) |
12 % |
NumberFormat.getPercentInstance().format( 0.123 ) |
Jede dieser Klassen implementiert auf jeden Fall die Methode zur Ausgabe, format(), und zur Erkennung, parseObject().
abstract class java.text.Format
implements Serializable, Cloneable |
- String format( Object obj )
Formatiert das Objekt obj und gibt eine Zeichenkette zurück.
- abstract StringBuffer format( Object obj, StringBuffer toAppendTo, FieldPosition pos ) Formatiert ein Objekt und hängt den Text an den angegebenen StringBuffer an. (Eine Methode mit StringBuilder gibt es nicht.) Kann die Zeichenkette nicht mit format() nach den Regeln des Format-Objekts ausgegeben werden, löst die Methode eine IllegalArgumentException aus. Ist die Formatierungsanweisung falsch, so gibt format() das Unicode-Zeichen \uFFFD zurück.
- Object parseObject( String source )
Analysiert den Text von Anfang an.
- abstract Object parseObject( String source, ParsePosition pos )
Der Text wird ab der Stelle pos umgewandelt. Konnte parseObject() die Zeichenkette nicht zurückübersetzen, so folgt eine ParseException. parseObject(String, ParsePosition) verändert das ParsePosition-Objekt nicht und gibt die null-Referenz zurück.
- Object clone()
Gibt eine Kopie zurück.
- Die Mehrzahl der Format-Unterklassen implementiert Fabrikfunktionen der Art:
- static XXXFormat getYYYInstance()
Liefert ein Formatierungsobjekt mit den Formatierungsregeln für das voreingestellte Land.
- static XXXFormat getYYYInstance( Locale l )
Für ein Formatierungsobjekt mit den Formatierungsregeln für das angegebene Land. So erlauben die Unterklassen von Format es dem Benutzer auch, weitere Objekte zu erzeugen, die an die speziellen Sprachbesonderheiten der Länder angepasst sind.
4.9.3 Zahlen, Prozente und Währungen mit NumberFormat und DecimalFormat formatieren 

NumberFormat widmet sich der Ausgabe von Zahlen. Dabei unterstützt die Klasse mit statischen Fabrikfunktionen – also keinen Konstruktoren – vier Typen von Ausgaben:
abstract class java.text.NumberFormat
extends Format |
- static NumberFormat getNumberInstance()
Liefert den einfachen Formatierer für Zahlen.
- static NumberFormat getIntegerInstance()
Liefert einen Formatierer, der den Nachkommateil abschneidet und rundet.
- static NumberFormat getPercentInstance()
Liefert einen Formatierer, der Fließkommazahlen über die format()-Methode im Bereich von 0 bis 1 annimmt und dann als Prozentzahl formatiert. Nachkommastellen werden abgeschnitten.
- static NumberFormat getCurrencyInstance()
Liefert einen Formatierer für Währungen, der ein Währungszeichen zur Ausgabe hinzufügt.
Die genannten vier Funktionen gibt es jeweils in der parameterlosen Variante und in der Variante mit einem Locale-Objekt, um etwa das Währungszeichen oder das Kommazeichen anzupassen.
Dezimalzahlformatierung mit DecimalFormat
DecimalFormat ist eine Unterklasse von NumberFormat und ermöglicht individuellere Anpassungen an die Ausgabe. Dem Konstruktor kann ein Formatierungsstring übergeben werden, sozusagen eine Vorlage, wie die Zahlen zu formatieren sind. Die Formatierung einer Zahl durch DecimalFormat erfolgt mit Rücksicht auf die aktuell eingestellte Sprache.
Listing 4.25 DecimalFormatDemo.java, main()
double d = 12345.67890; DecimalFormat df = new DecimalFormat( "###,##0.00" ); System.out.println( df.format(d) ); // 12.345,68
Der Formatierungsstring kann eine Menge von Formatierungsanweisungen vertragen; im Beispiel kommen #, 0 und das Komma vor. Die beiden wichtigen Symbole sind jedoch 0 und #. Beide repräsentieren Ziffern. Der Unterschied tritt erst dann zutage, wenn weniger Zeichen zum Formatieren da sind, als im Formatierungsstring genannt werden.
Symbol | Bedeutung |
0 |
Repräsentiert eine Ziffer – ist die Stelle nicht belegt, wird eine Null angezeigt. |
# |
Repräsentiert eine Ziffer – ist die Stelle nicht belegt, bleibt sie leer, damit führende Nullen und unnötige Nullen hinter dem Komma nicht angezeigt werden. |
. |
Dezimaltrenner. Trennt Vor- und Nachkommastellen. |
, |
Gruppiert die Ziffern (eine Gruppe ist so groß wie der Abstand von »,« zu ».«). |
; |
Trennzeichen. Links davon steht das Muster für positive Zahlen, rechts das für negative Zahlen. |
- |
das Standardzeichen für das Negativpräfix |
% |
Die Zahl wird mit 100 multipliziert und als Prozentwert ausgewiesen. |
\u2030 |
Die Zahl wird mit 1.000 multipliziert und als Promillewert ausgezeichnet. |
\u00A4 |
nationales Währungssymbol (€ für Deutschland) |
\u00A4\u00A4 |
internationales Währungssymbol (EUR für Deutschland) |
X |
Alle anderen Zeichen – symbolisch X – können ganz normal benutzt werden. |
' |
Ausmarkieren von speziellen Symbolen im Präfix oder Suffix |
Hier ein Beispiel für die Auswirkungen der Formatanweisungen auf einige Zahlen:
Format | Eingabezahl | Ergebnis |
0000 |
12 |
0012 |
0000 |
12,5 |
0012 |
0000 |
1234567 |
1234567 |
## |
12 |
12 |
## |
12.3456 |
12 |
## |
123456 |
123456 |
.00 |
12.3456 |
12,35 |
.00 |
.3456 |
,35 |
0.00 |
.789 |
0,79 |
#.000000 |
12.34 |
12,340000 |
,### |
12345678.901 |
12.345.679 |
#.#;(#.#) |
12345678.901 |
12345678,9 |
#.#;(#.#) |
–12345678.901 |
(12345678,9) |
,###.## \u00A4 |
12345.6789 |
12.345,68 € |
,#00.00 \u00A4\u00A4 |
–12345678.9 |
–12.345.678,90 € |
,#00.00 \u00A4\u00A4 |
0.1 |
00,10 € |