5.11Die Default-Falle
Insbesondere bei Kodierungen und zeitgebundenen Eigenschaften müssen sich Entwickler zu jeder Zeit bewusst sein, welche Einstellung gerade verwendet wird. Neulinge greifen oft auf Default-Einstellungen zurück, und String-Parsing mit Scanner und Ausgaben mit Formatter funktionieren in der Entwicklung. Doch spätestens wenn die Software halb um den Globus wandert, läuft nichts mehr, weil die Default-Werte plötzlich anders sind.
Wenn Konstruktoren oder Methoden es nicht explizit verlangen, greift das JDK auf Standardwerte zurück, unter anderem für:
Zeilenendezeichen
Zeichenkodierung
Sprache (Locale)
Zeitzone (TimeZone)
Ein Beispiel: Der Konstruktor Scanner(File) öffnet eine Datei zum Lesen und konvertiert die Bytes in Unicodes mit einem Konverter, den die Default-Zeichenkodierung bestimmt. Wird aus dem Scanner eine Zahl gelesen, etwa mit nextDouble(), greift die voreingestellte Default-Locale, die dem Scanner sagt, ob Dezimalzahlen mit »,« oder ».« interpretiert werden müssen. Verarbeitet ein Java-Programm die gleiche Textdatei einmal in den USA und einmal in Deutschland, ist das Ergebnis unterschiedlich, und in der Regel sollte das nicht so sein.
Default-Werte sind eine gute Sache, allerdings sollten sich Entwickler bewusst sein, an welchen Stellen das JDK auf sie zurückgreift, um keine Überraschungen zu erleben. Es lohnt sich, immer konkrete Belegungen anzugeben, auch wenn als Argument zum Beispiel Locale.getDefault() steht. Das dokumentiert das gewollte Nutzen der Default-Werte. In Java 8 sind dann einige Methoden/Konstruktoren ergänzt worden, die standardmäßig als Dateikodierung UTF-8 annehmen, das macht das Chaos natürlich komplett. Zwei Beispiele:
Files.newBufferedReader(Path)
Files.lines(Path)
Natürlich ist UTF-8 immer eine gute Standardbelegung, nur sollten sich Entwickler bewusst sein, dass ein new FileReader(File) eben mit dem Default-Charset arbeitet, und newBufferedReader(Path) mit UTF-8.