Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Objektorientierte Beziehungsfragen
7 Ausnahmen müssen sein
8 Äußere.innere Klassen
9 Besondere Typen der Java SE
10 Generics<T>
11 Lambda-Ausdrücke und funktionale Programmierung
12 Architektur, Design und angewandte Objektorientierung
13 Die Klassenbibliothek
14 Einführung in die nebenläufige Programmierung
15 Einführung in Datenstrukturen und Algorithmen
16 Einführung in grafische Oberflächen
17 Einführung in Dateien und Datenströme
18 Einführung ins Datenbankmanagement mit JDBC
19 Einführung in <XML>
20 Testen mit JUnit
21 Bits und Bytes und Mathematisches
22 Die Werkzeuge des JDK
A Java SE Paketübersicht
Stichwortverzeichnis

Download:
- Beispielprogramme, ca. 20,0 MB
- Übungsaufgaben, ca. 1,8 MB
- Musterlösungen, ca. 0,8 MB

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenbloom
Das umfassende Handbuch
Buch: Java ist auch eine Insel

Java ist auch eine Insel
Rheinwerk Computing
1306 Seiten, gebunden, 11. Auflage
49,90 Euro, ISBN 978-3-8362-2873-2
Pfeil 13 Die Klassenbibliothek
Pfeil 13.1 Die Java-Klassenphilosophie
Pfeil 13.1.1 Übersicht über die Pakete der Standardbibliothek
Pfeil 13.1.2 Compact-Profile
Pfeil 13.2 Sprachen der Länder
Pfeil 13.2.1 Sprachen und Regionen über Locale-Objekte
Pfeil 13.3 Die Klasse Date
Pfeil 13.3.1 Objekte erzeugen und Methoden nutzen
Pfeil 13.3.2 Date-Objekte sind nicht immutable
Pfeil 13.4 Calendar und GregorianCalendar
Pfeil 13.4.1 Die abstrakte Klasse Calendar
Pfeil 13.4.2 Calendar nach Date und Millisekunden fragen
Pfeil 13.4.3 Abfragen und Setzen von Datumselementen über Feldbezeichner
Pfeil 13.4.4 Kalender-Exemplare bauen über den Calendar.Builder
Pfeil 13.4.5 Der gregorianische Kalender
Pfeil 13.4.6 Date-Time-API in Java 8
Pfeil 13.5 Klassenlader (Class Loader) und Klassenpfad
Pfeil 13.5.1 Woher die kleinen Klassen kommen
Pfeil 13.5.2 Setzen des Klassenpfades
Pfeil 13.5.3 Die wichtigsten drei Typen von Klassenladern
Pfeil 13.6 Die Utility-Klasse System und Properties
Pfeil 13.6.1 Systemeigenschaften der Java-Umgebung
Pfeil 13.6.2 line.separator
Pfeil 13.6.3 Eigene Properties von der Konsole aus setzen *
Pfeil 13.6.4 Umgebungsvariablen des Betriebssystems *
Pfeil 13.6.5 Einfache Zeitmessung und Profiling *
Pfeil 13.7 Einfache Benutzereingaben
Pfeil 13.7.1 Grafischer Eingabedialog über JOptionPane
Pfeil 13.7.2 Geschützte Passwort-Eingaben mit der Klasse Console *
Pfeil 13.8 Ausführen externer Programme *
Pfeil 13.8.1 ProcessBuilder und Prozesskontrolle mit Process
Pfeil 13.8.2 Einen Browser, E-Mail-Client oder Editor aufrufen
Pfeil 13.9 Benutzereinstellungen *
Pfeil 13.9.1 Benutzereinstellungen mit der Preferences-API
Pfeil 13.9.2 Einträge einfügen, auslesen und löschen
Pfeil 13.9.3 Auslesen der Daten und Schreiben in einem anderen Format
Pfeil 13.9.4 Auf Ereignisse horchen
Pfeil 13.9.5 Zugriff auf die gesamte Windows-Registry
Pfeil 13.10 Zum Weiterlesen
 
Zum Seitenanfang

13.6Die Utility-Klasse System und Properties Zur vorigen ÜberschriftZur nächsten Überschrift

In der Klasse java.lang.System finden sich Methoden zum Erfragen und Ändern von Systemvariablen, zum Umlenken der Standarddatenströme, zum Ermitteln der aktuellen Zeit, zum Beenden der Applikation und noch für das ein oder andere. Alle Methoden sind ausschließlich statisch, und ein Exemplar von System lässt sich nicht anlegen. In der Klasse java.lang.Runtime – die Schnittstelle RunTime aus dem CORBA-Paket hat hiermit nichts zu tun – finden sich zusätzlich Hilfsmethoden, wie etwa für das Starten von externen Programmen oder Methoden zum Erfragen des Speicherbedarfs. Anders als System ist hier nur eine Methode statisch, nämlich die Singleton-Methode getRuntime(), die das Exemplar von Runtime liefert.

Bemerkung

Insgesamt machen die Klassen System und Runtime keinen besonders aufgeräumten Eindruck; sie wirken irgendwie so, als sei hier alles zu finden, was an anderer Stelle nicht mehr hineingepasst hat. Auch wären Methoden einer Klasse genauso gut in der anderen Klasse aufgehoben.

Dass die statische Methode System.arraycopy(…) zum Kopieren von Feldern nicht in java.util.Arrays stationiert ist, lässt sich nur historisch erklären. Und System.exit(int) leitet an Runtime.getRuntime().exit(int) weiter. Einige Methoden sind veraltet bzw. anders verteilt: Das exec(…) von Runtime zum Starten von externen Prozessen übernimmt eine neue Klasse ProcessBuilder, und die Frage nach dem Speicherzustand oder der Anzahl der Prozessoren beantworten MBeans, wie etwa ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors(). Aber API-Design ist wie Sex: Eine unüberlegte Aktion, und es lebt mit uns für immer.

Eigenschaften der Klassen System und Runtime

Abbildung 13.1Eigenschaften der Klassen System und Runtime

 
Zum Seitenanfang

13.6.1Systemeigenschaften der Java-Umgebung Zur vorigen ÜberschriftZur nächsten Überschrift

Die Java-Umgebung verwaltet Systemeigenschaften wie Pfadtrenner oder die Version der virtuellen Maschine in einem java.util.Properties-Objekt. Die statische Methode System.getProperties() erfragt diese Systemeigenschaften und liefert das gefüllte Properties-Objekt zurück. Zum Erfragen einzelner Eigenschaften ist das Properties-Objekt aber nicht unbedingt nötig: System.getProperty(…) erfragt direkt eine Eigenschaft.

[zB]Beispiel

Gib den Namen des Betriebssystems aus:

System.out.println( System.getProperty("os.name") ); // z. B. Windows 7

Gib alle Systemeigenschaften auf dem Bildschirm aus:

System.getProperties().list( System.out );

Die Ausgabe beginnt mit:

-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Program Files\Java\jdk1.8.0\jre\bin
java.vm.version=25.0-b70
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
path.separator=;

Eine Liste der wichtigen Standardsystemeigenschaften:

Schlüssel

Bedeutung

java.version

Version der Java-Laufzeitumgebung

java.class.path

Klassenpfad

java.library.path

Pfad für native Bibliotheken

java.io.tmpdir

Pfad für temporäre Dateien

os.name

Name des Betriebssystems

file.separator

Trenner der Pfadsegmente, etwa / (Unix) oder \ (Windows)

path.separator

Trenner bei Pfadangaben, etwa : (Unix) oder ; (Windows)

line.separator

Zeilenumbruchzeichen(folge)

user.name

Name des angemeldeten Benutzers

user.home

Home-Verzeichnis des Benutzers

user.dir

aktuelles Verzeichnis des Benutzers

Tabelle 13.6Standardsystemeigenschaften

API-Dokumentation

Ein paar weitere Schlüssel zählt die API-Dokumentation bei System.getProperties() auf. Einige der Variablen sind auch anders zugänglich, etwa über die Klasse File.

final class java.lang.System

  • static String getProperty(String key)
    Gibt die Belegung einer Systemeigenschaft zurück. Ist der Schlüssel null oder leer, gibt es eine NullPointerException bzw. eine IllegalArgumentException.

  • static String getProperty(String key, String def)
    Gibt die Belegung einer Systemeigenschaft zurück. Ist sie nicht vorhanden, liefert die Methode die Zeichenkette def, den Default-Wert. Für die Ausnahmen gilt das Gleiche wie bei getProperty(String).

  • static String setProperty(String key, String value)
    Belegt eine Systemeigenschaft neu. Die Rückgabe ist die alte Belegung – oder null, falls es keine alte Belegung gab.

  • static String clearProperty(String key)
    Löscht eine Systemeigenschaft aus der Liste. Die Rückgabe ist die alte Belegung – oder null, falls es keine alte Belegung gab.

  • static Properties getProperties()
    Liefert ein mit den aktuellen Systembelegungen gefülltes Properties-Objekt.

 
Zum Seitenanfang

13.6.2line.separator Zur vorigen ÜberschriftZur nächsten Überschrift

Um nach dem Ende einer Zeile an den Anfang der nächsten zu gelangen, wird ein Zeilenumbruch (engl. new line) eingefügt. Das Zeichen für den Zeilenumbruch muss kein einzelnes sein, es können auch mehrere Zeichen nötig sein. Zum Leidwesen der Programmierer unterscheidet sich die Anzahl der Zeichen für den Zeilenumbruch auf den bekannten Architekturen:

  • Unix: Line Feed (Zeilenvorschub)

  • Macintosh: Carriage Return (Wagenrücklauf)

  • Windows: beide Zeichen (Carriage Return und Line Feed)

Der Steuercode für Carriage Return (kurz CR) ist 13 (0x0D), der für Line Feed (kurz LF) 10 (0x0A). Java vergibt obendrein eigene Escape-Sequenzen für diese Zeichen: \r für Carriage Return und \n für Line Feed (die Sequenz \f für einen Form Feed – Seitenvorschub – spielt bei den Zeilenumbrüchen keine Rolle).

Bei der Ausgabe mit einem printXXX(…) oder der Nutzung des Formatspezifizierers %n in format(…) bzw. printf(…) haben wir bei Zeilenumbrüchen keinerlei Probleme. So ist es oft gar nicht nötig, das Zeilenumbruchzeichen vom System über die Property line.separator zu erfragen.

 
Zum Seitenanfang

13.6.3Eigene Properties von der Konsole aus setzen * Zur vorigen ÜberschriftZur nächsten Überschrift

Eigenschaften lassen sich auch beim Programmstart von der Konsole aus setzen. Dies ist praktisch für eine Konfiguration, die beispielsweise das Verhalten des Programms steuert. In der Kommandozeile werden mit -D der Name der Eigenschaft und nach einem Gleichheitszeichen (ohne Weißraum) ihr Wert angegeben. Das sieht dann etwa so aus:

$ java -DLOG –DUSER=Chris -DSIZE=100 com.tutego.insel.lang.SetProperty

Die Property LOG ist einfach nur »da«, aber ohne zugewiesenen Wert. Die nächsten beiden Properties, USER und SIZE, sind mit Werten verbunden, die erst einmal vom Typ String sind und vom Programm weiterverarbeitet werden müssen. Die Informationen tauchen nicht bei der Argumentliste in der statischen main(String[])-Methode auf, da sie vor dem Namen der Klasse stehen und bereits von der Java-Laufzeitumgebung verarbeitet werden.

Um die Eigenschaften auszulesen, nutzen wir das bekannte System.getProperty(…):

Listing 13.5com/tutego/insel/lang/SetProperty.java, main()

String logProperty = System.getProperty( "LOG" );
String usernameProperty = System.getProperty( "USER" );
String sizeProperty = System.getProperty( "SIZE" );

System.out.println( logProperty != null ); // true
System.out.println( usernameProperty ); // Chris

if ( sizeProperty != null )
System.out.println( Integer.parseInt( sizeProperty ) ); // 100

System.out.println( System.getProperty( "DEBUG", "false" ) ); // false
Entwicklungsumgebungen erlauben es, die Kommandozeilenargumente in einem Fenster zu setzen. Unter Eclipse gehen wir dazu unter »Run • Run Configurations«, dann zu »Arguments«.

Abbildung 13.2Entwicklungsumgebungen erlauben es, die Kommandozeilenargumente in einem Fenster zu setzen. Unter Eclipse gehen wir dazu unter »Run • Run Configurations«, dann zu »Arguments«.

Wir bekommen über getProperty(String) einen String zurück, der den Wert anzeigt. Falls es überhaupt keine Eigenschaft dieses Namens gibt, erhalten wir stattdessen null. So wissen wir auch, ob dieser Wert überhaupt gesetzt wurde. Ein einfacher Test wie bei logProperty != null sagt also, ob logProperty vorhanden ist oder nicht. Statt -DLOG führt auch -DLOG= zum gleichen Ergebnis, denn der assoziierte Wert ist der Leer-String. Da alle Properties erst einmal vom Typ String sind, lässt sich usernameProperty einfach ausgeben, und wir bekommen entweder null oder den hinter = angegebenen String. Sind die Typen keine Strings, müssen sie weiterverarbeitet werden, also etwa mit Integer.parseInt(), Double.parseDouble() usw. Nützlich ist die Methode System.getProperty(String, String), der zwei Argumente übergeben werden, denn das zweite steht für einen Default-Wert. So kann immer ein Standardwert angenommen werden.

Boolean.getBoolean(String)

Im Fall von Properties, die mit Wahrheitswerten belegt werden, kann Folgendes geschrieben werden:

boolean b = Boolean.parseBoolean( System.getProperty(property) ); // (*)

Für die Wahrheitswerte gibt es eine andere Variante. Die statische Methode Boolean.getBoolean(String) sucht aus den System-Properties eine Eigenschaft mit dem angegebenen Namen heraus. Analog zur Zeile (*) ist also:

boolean b = Boolean.getBoolean( property );

Es ist schon erstaunlich, diese statische Methode in der Wrapper-Klasse Boolean anzutreffen, weil Property-Zugriffe nichts mit den Wrapper-Objekten zu tun haben und die Klasse hier eigentlich über ihre Zuständigkeit hinausgeht.

Gegenüber einer eigenen, direkten System-Anfrage hat getBoolean(String) auch den Nachteil, dass wir bei der Rückgabe false nicht unterscheiden können, ob es die Eigenschaft schlichtweg nicht gibt oder ob die Eigenschaft mit dem Wert false belegt ist. Auch falsch gesetzte Werte wie -DP=fa1se ergeben immer false.[ 219 ]

final class java.lang.Boolean
implements Serializable, Comparable<Boolean>

  • static boolean getBoolean(String name)
    Liest eine Systemeigenschaft mit dem Namen name aus und liefert true, wenn der Wert der Property gleich dem String "true" ist. Die Rückgabe ist false, wenn entweder der Wert der Systemeigenschaft "false" ist oder er nicht existiert oder null ist.

 
Zum Seitenanfang

13.6.4Umgebungsvariablen des Betriebssystems * Zur vorigen ÜberschriftZur nächsten Überschrift

Fast jedes Betriebssystem nutzt das Konzept der Umgebungsvariablen (engl. environment variables); bekannt ist etwa PATH für den Suchpfad für Applikationen unter Windows und unter Unix. Java macht es möglich, auf diese System-Umgebungsvariablen zuzugreifen. Dazu dienen zwei statische Methoden:

final class java.lang.System

  • static Map<String, String> getEnv()
    Liest eine Menge von <String, String>-Paaren mit allen Systemeigenschaften.

  • static String getEnv(String name)
    Liest eine Systemeigenschaft mit dem Namen name. Gibt es sie nicht, ist die Rückgabe null.

[zB]Beispiel

Was ist der Suchpfad? Den liefert System.getenv("path");

Name der Variablen

Beschreibung

Beispiel

COMPUTERNAME

Name des Computers

MOE

HOMEDRIVE

Laufwerksbuchstabe des Benutzerverzeichnisses

C

HOMEPATH

Pfad des Benutzerverzeichnisses

\Users\Christian

OS

Name des Betriebssystems

Windows_NT

PATH

Suchpfad

C:\windows\SYSTEM32;
C:\windows

PATHEXT

Dateiendungen, die für ausführbare Programme stehen

.COM;.EXE;.BAT;.CMD;.VBS;.VBE; .JS;.JSE;.WSF;.WSH;.MSC

SYSTEMDRIVE

Laufwerksbuchstabe des Betriebssystems

C

TEMP und auch TMP

temporäres Verzeichnis

C:\Users\CHRIST~1\
AppData\Local\Temp

USERDOMAIN

Domäne des Benutzers

MOE

USERNAME

Name des Nutzers

Christian

USERPROFILE

Profilverzeichnis

C:\Users\Christian

WINDIR

Verzeichnis des Betriebssystems

C:\windows

Tabelle 13.7Auswahl einiger unter Windows verfügbarer Umgebungsvariablen

Einige der Variablen sind auch über die System-Properties (System.getProperties(), System.getProperty(…)) erreichbar.

[zB]Beispiel

Gib die Umgebungsvariablen des Systems aus. Um die Ausgabe etwas übersichtlicher zu gestalten, ist bei der Aufzählung jedes Komma durch ein Zeilenvorschubzeichen ersetzt worden:

Map<String,String> map = System.getenv();
System.out.println( map.toString().replace(',', '\n') );
 
Zum Seitenanfang

13.6.5Einfache Zeitmessung und Profiling * Zur vorigen ÜberschriftZur nächsten Überschrift

Neben den komfortablen Klassen zum Verwalten von Datumswerten gibt es mit zwei statischen Methoden einfache Möglichkeiten, Zeiten für Programmabschnitte zu messen:

final class java.lang.System

  • static long currentTimeMillis()
    Gibt die seit dem 1.1.1970 vergangenen Millisekunden zurück.

  • static long nanoTime()
    Liefert die Zeit vom genauesten System-Zeitgeber. Sie hat keinen Bezugspunkt zu irgendeinem Datum; seit dem 1.1.1970 sind so viele Nanosekunden vergangen, dass sie gar nicht in den long passen würden.

Die Differenz zweier Zeitwerte kann der groben Abschätzung von Ausführungszeiten von Programmen dienen:

Listing 13.6com/tutego/insel/lang/Profiling.java

package com.tutego.insel.lang;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

class Profiling {
private static long[] measure() {
final int MAX = 10000;

final String string = "Aber Angie, Angie, ist es nicht an der Zeit, Goodbye
zu sagen? " +
"Ohne Liebe in unseren Seelen und ohne Geld in unseren
Mänteln. " +
"Du kannst nicht sagen, dass wir zufrieden sind.";

final int number = 123;
final double nullnummer = 0.0;

// StringBuffer(size) und append() zur Konkatenation

long time1 = System.nanoTime();

final StringBuilder sb1 = new StringBuilder( MAX * (string.length() + 6) );
for ( int i = MAX; i-- > 0; )
sb1.append( string ).append( number ).append( nullnummer );
sb1.toString();

time1 = NANOSECONDS.toMillis( System.nanoTime()time1 );

// StringBuffer und append() zur Konkatenation

long time2 = System.nanoTime();

final StringBuilder sb2 = new StringBuilder();
for ( int i = MAX; i-- > 0; )
sb2.append( string ).append( number ).append( nullnummer );
sb2.toString();

time2 = NANOSECONDS.toMillis( System.nanoTime()time2 );

// + zur Konkatenation

long time3 = System.nanoTime();

String t = "";
for ( int i = MAX; i-- > 0; )
t += string + number + nullnummer;

time3 = NANOSECONDS.toMillis( System.nanoTime()time3 );

return new long[] { time1, time2, time3 };
}

public static void main( String[] args ) {
measure(); System.gc(); measure(); System.gc();
long[] durations = measure();

System.out.printf( "sb(size), append(): %d ms%n", durations[0] );
// sb(size), append(): 2 ms
System.out.printf( "sb(), append() : %d ms%n", durations[1] );
// sb(), append() : 21 ms
System.out.printf( "t+= : %d ms%n", durations[2] );
// t+= : 10661 ms
}
}

Das Testprogramm hängt Zeichenfolgen mit

  • einem StringBuilder, der nicht in der Endgröße initialisiert ist,

  • einem StringBuilder, der eine vorinitialisierte Endgröße nutzt, und

  • dem Plus-Operator von Strings zusammen.

Vor der Messung gibt es zwei Testläufe und ein System.gc(), was die automatische Speicherbereinigung (GC) anweist, Speicher freizugeben. (Das würde in gewöhnlichen Programmen nicht stehen, da der Garbage-Collector schon selbst ganz gut weiß, wann Speicher freizugeben ist. Nur kostet das Freigeben auch Ausführungszeit, und es würde die Messzeiten beeinflussen, was wir hier nicht wollen.)

Auf meinem Rechner (JDK 8) liefert das Programm die Ausgabe:

sb(size), append(): 7 ms
sb(), append() : 10 ms
t+= : 41262 ms

Das Ergebnis: Bei großen Anhänge-Operationen ist es ein wenig besser, einen passend in der Größe initialisierten StringBuilder zu benutzen. Über das + entstehen viele temporäre Objekte, was wirklich teuer kommt. Aber auch, wenn der StringBuilder nicht die passende Größe enthält, sind die Differenzen nahezu unbedeutend.

Wo im Programm überhaupt Taktzyklen verbraten werden, zeigt ein Profiler. An diesen Stellen kann dann mit der Optimierung begonnen werden. Java Mission Control bzw, Java VisualVM (http://visualvm.java.net/) integrieren ein freier Profiler und sind Teil vom JDK. Der JVM Monitor (http://www.jvmmonitor.org/index.html) ist ein kleines freies Plugin für Eclipse. NetBeans integriert einen Profiler, Informationen liefert http://profiler.netbeans.org.

 


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
 Zum Katalog
Zum Katalog: Java ist auch eine Insel Java ist auch eine Insel
Jetzt bestellen

 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Java SE 8 Standard-Bibliothek
Java SE 8 Standard-Bibliothek


Zum Katalog: Professionell entwickeln mit Java EE 7
Professionell entwickeln mit Java EE 7


Zum Katalog: Schrödinger programmiert Java
Schrödinger programmiert Java


Zum Katalog: Einführung in Java
Einführung in Java


Zum Katalog: Programmieren lernen mit Java
Programmieren lernen mit Java


Zum Katalog: Apps entwickeln für Android 5
Apps entwickeln für Android 5


Zum Katalog: Apps entwickeln mit Android Studio
Apps entwickeln mit Android Studio


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2016
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de