Wyświetlanie wyników działania programu jest jednym z najważniejszych interakcji z użytkownikiem. Ten, wprowadzając do programu dane oczekuje ich przetworzenia i zwrócenia wyników w postaci czytelnych komunikatów i przetworzonych owych danych.
System.out
Java w konsolowej komunikacji używa dwu kanałów tworzenia komunikatów na konsoli (monitorze). Jeden z nich, już wspomniany to strumień out1Po prawdzie strumień ten jest strumieniem stworzonym jako strumień klasy PrintStream i w opisie tej klasy należałoby szukać metod jego obsługi. obiektu System z wszystkimi przynależnymi mu metodami.
Formatowanie wyjścia, czyli strumienia out po części może zostać zrealizowane za pomocą tych metod.
- print(typ zmienna); – wyświetl na konsoli zawartość zmiennej zmienna typu typ.
- println(typ zmienna); – wyświetl na konsoli zawartość zmiennej zmienna typu typ i przejdź do następnej linii.
- printf(typ zmienna); – wyświetl na konsoli sformatowany ciąg znaków używając ciągu formatującego i argumentów.
Na chwilę obecną można wspomnieć, że metody te są przeciążone i w klasie PrintStream są zdefiniowane dla wszystkich możliwych predefiniowanych typów2Co to jest przeciążanie metod dowiemy się w „obiektowej” części tego kursu programowania. Dla nas ważne jest, że nie musimy się przejmować jakiego typu jest parametr umieszczany w nawiasach i czy jest on typu int, czy float, czy też jest typu String, tak jak na poniższym przykładzie. System sam określi typ parametru i odpowiednio obsłuży wyświetlanie.
System.out.println("Ala ma kota");
Ciekawym jest znany także w innych językach sposób formatowania za pomocą metody printf(); Używa on jako pierwszego argumentu ciągu formatującego, a następnie listy argumentów, które po kolei „wstrzykuje” w treść ciągu we wskazanych miejscach i we wskazany sposób, tak jak poniżej na przykładach.
public static void main(String[] args) {
String imie="Ala";
int wiek=21, wzrost=176;
final String plec="Kobieta";
double czesne=341.76d;
System.out.printf("%s, studentka %s mająca lat %d ma wzrostu %dcm opłaca studia kwotą %f\n\n", plec, imie, wiek, wzrost, czesne);
//Kobieta, studentka Ala mająca lat 21 ma wzrostu 176cm opłaca studia kwotą 341,760000
System.out.printf("%s, studentka %s mająca lat %d ma wzrostu %dcm opłaca studia kwotą %10.2f \n\n", plec, imie, wiek, wzrost, czesne);
//Kobieta, studentka Ala mająca lat 21 ma wzrostu 176cm opłaca studia kwotą 341,76
}
Poeksperymentuj z powyższym kodem próbując zmienić sposób w jaki wyświetlane są użyte zmienne. Udało Ci się uniknąć błędu i wygenerowania wyjątku?!3Jeśli pomylimy się w zgodności użytego kwalifikatora wartości z podanym w liście typem argumentu to program taki „wyrzuci” nam błąd. Tym błędem najprawdopodobniej będzie: IllegalFormatConversionException. Jeśli, w przypadku, gdy nie przygotujemy wystarczającej liczby argumentów aby uzupełnić ciąg formatujący, to błędem będzie: MissingFormatArgumentException.
Jeśli zaś pomylimy się w określaniu konwersji wartości to błędem może być: UnknownFormatConversionException lub MissingFormatWidthException. O błędach i ich przechwytywaniu będzie jeszcze cały temat.
Zwróć uwagę jednak na różnice w formatowaniu liczb. W powyższym przykładzie drobna zmiana w ciągu formatującym znakomicie poprawiła nam czytelność wyniku. Za pierwszym razem wyświetliliśmy użytą wartość double jako: 341,760000, a za drugim razem sformatowaliśmy wynik tak, aby na 10 polach wyświetlił tę liczbę używając tylko dwu miejsc po przecinku. Prawda, że estetyczniej?! Poniżej kilka najprzydatniejszych formatowań i efekt ich działania:
double x=173.4563464574854633d;
System.out.println(x);
System.out.printf("%f \n",x);
System.out.printf("%10.3f \n",x);
System.out.printf("%010.3f \n",x);
System.out.printf("%-10.4f \n",x);
System.out.printf("%+10.0f \n",x);

Odnosząc się do powyższego przykładu można kolejno omówić formatowanie jako:
- brak formatowania, wyświetlenie liczby jako double (porównaj wartość przypisaną do zmiennej i wyświetloną),
- format bez justowania, po przecinku z precyzją float,
- formatowanie do prawej na 10 znakach, 3 cyfry po przecinku,
- formatowanie z uzupełnieniem wiodącym „0” na 10 znakach, 3 cyfry po przecinku,
- formatowanie do lewej na 10 znakach, 3 cyfry po przecinku,
- formatowanie do prawej na 10 znakach, 0 cyfr po przecinku, ze znakiem plusa.
Opis formatowania wraz z selektorami formatowania można znaleźć w dokumentacji Javy, gdzie odsyłam zainteresowanych (a wydaje mi się, że zainteresowani winni być wszyscy).
System.err
Drugim strumieniem wyjściowym jest err, równoległy do, i niezależny od pierwszego, wymienionego wyżej strumienia out4Równoległy znaczy: nie sekwencyjny!!! Ma to wydźwięk w tym, że oba procesy opróżniania buforów do strumieni zachodzą od siebie niezależnie i zasadniczo nie mamy wpływu na to który komunikat, z którego kanału (strumienia) pojawi się jako pierwszy na konsoli. Charakterystyczną cechą strumienia err jest kolor czerwony takiego komunikatu. Strumień ten także jest elementem stworzonym na klasie PrintStream, wobec czego dotyczą go takie same zasady jak w przypadku out. Nasz przykład kodu z naprzemiennym wykorzystaniem strumieni wygląda tak:
double x=173.4563464574854633d;
System.out.println(x);
System.err.printf("%f \n",x);
System.out.printf("%10.3f \n",x);
System.err.printf("%010.3f \n",x);
System.out.printf("%-10.4f \n",x);
System.err.printf("%+10.0f \n",x);
A efekt jego działania poniżej:

Proszę jednakże zapamiętać, że strumień err nie powinien być traktowany bezkrytycznie jako sposób pokolorowania komunikatu na kolor czerwony! Nie możemy także zakładać, że komunikaty wyświetlą się w kolejności zgodnej z sekwencją linii kodu! Jakiekolwiek opóźnienie w realizacji któregoś z podprogramów systemowych spowoduje przesunięcie ich kolejności względem siebie.
Temat formatowania nie został niniejszym wyczerpany i będzie stanowił jeszcze podstawę rozszerzenia w późniejszych modułach.
Zadanie do samodzielnego opracowania: Zapoznać się ze sposobami wyświetlania różnych wartości różnych typów. Poeksperymentować z formatowaniem wyświetlanych danych w oknie konsoli.