Javas Locale ist dumm
Mal wieder ein Problem mit Java: Der Konstruktor von Locale
ist dumm.
Man kann als language alles angeben, also nicht nur den geforderten 2-Zeichen-Code (z.B. de oder en). Dadurch kommt es im späteren Verlauf zu Problemen, da viele Methoden nicht mehr funktionieren. Eigentlich kann man erwarten, dass der Konstruktor das überprüft, sodass nur "legale" Instanzen von Locale erzeugt werden können. Ist aber nicht so.
Aufgefallen ist mir das bei der Entwicklung einer kleinen Bibliothek, die zwar keine Abhängigkeiten zu Android hat, aber vorerst nur dort laufen soll. Entwickelt habe ich sie in Java 7 und erstmal nicht weiter auf Abwärtskompatibilität geachtet.
Konkret geht es um die Methode Locale.forLanguageTag(String)
, welche zu einem gegebenen 3-Zeichen-Sprachcode (z.B. eng oder deu) eine entsprechende Instanz von Locale
liefert. Doch Android nutzt noch die Java 6 API, bei der diese Methode noch nicht vorhanden ist. Also hat ein anderer Entwickler einfach ein (hier als Beispiel) new Locale("eng")
gemacht - und da der Konstruktor dumm ist, funktioniert das auch.
Problematisch wird es erst, wenn man diese Instanz von Locale
benutzen möchte. Bei uns ist das Locale.getISO3Language()
, was wieder einen 3-Zeichen-Code zurück gibt. Hier gibt es (zumindest in Java 6) eine nette Exception:
MissingResourceException: Couldn't find 3-letter language code for eng
Java 6 versucht nämlich einfach für den in language gespeicherten String einen 3-Zeichen-Code zu finden. Dumm nur, dass die Keys 2-Zeichen-Codes sind. In Java 7 gibt es hingegen eine Überprüfung und wenn der String bereits drei Zeichen lang ist, wird er direkt zurückgegeben.