Einleitung

In Java steht das Konzept der Internationalisierung zur Verfügung, um Anwendungen entwickeln zu können, deren Benutzeroberflächen Bezeichnungen in landesspezifischer Sprache enthalten. Manchmal wird der Begriff Internationalisierung auch mit i18n abgekürzt, da im Englischen 18 Buchstaben zwischen dem ersten i und dem letzten n des Worts Internationalization stehen. Ein internationalisiertes Programm weist die folgenden Kennzeichen auf:

  • Durch das Hinzufügen von Daten mit lokalem Bezug ist eine Anwendung in der Lage, Texte weltweit in der jeweiligen Landessprache anzuzeigen.
  • Textelemente, wie bspw. Fehlermeldungen und Komponentenbezeichner einer Benutzeroberfläche, werden nicht fest in einem Programm verdrahtet, sondern außerhalb des Quellcodes verankert und dynamisch hinzugebunden.
  • Die Unterstützung weiterer Sprachen erfordert keine erneute Übersetzung der Anwendung.
  • Weitere kulturabhängige Daten, wie bspw. das Datum oder Währungen, erscheinen in Formaten, die mit der Region und Sprache des Endbenutzers konform sind.

Unter der Lokalisierung versteht man den Prozess, Software an eine spezielle Region oder Sprache anzupassen, indem spezifische Komponenten hinzugefügt werden und Text übersetzt wird. Der Begriff Lokalisierung wird meist als l10n abgekürzt, da im Englischen 10 Buchstaben zwischen dem l und dem n des Worts Localization stehen. Der Kontext, in dem derartige sprachspezifische Bezeichnungen gespeichert werden, wird in Java auch als Locale bezeichnet. Den größte Zeitbedarf der Lokalisierungsphase nimmt die Übersetzung von Text in Anspruch. Andere Datentypen, wie bspw. Klangdateien oder Bilder, müssen oft nur dann angepasst werden, wenn sie kulturabhängig sind. Java garantiert in diesem Zusammenhang, dass die Formatierung von Datumsangaben, Zahlen und Währungen an lokale Erfordernisse automatisch durchgeführt wird.

Das folgende Beispiel illustriert die grundsätzliche Verwendung dieses Konzepts. Die zum detaillierten Verständnis notwendigen Bestandteile werden im Anschluss genauer erläutert. Das folgende Programm begrüßt in zwei Zeilen einen Benutzer:

code 

System.out.println("Hallo.");
System.out.println("Willkommen in Java!");

Offensichtlich ist das Programm für Anwender im englischsprachigen Raum ungeeignet. Da die Anwendung nicht multilingual arbeitet, muss der Entwickler die Texte ins Englische übersetzen. Meist sind allerdings Übersetzer nicht gleichzeitig Programmierer, so dass die Texte aus dem Quellcode in Textdateien gespeichert werden müssen, bevor sie von einem Übersetzer bearbeitet werden können. Das Programm muss weiterhin derart flexibel sein, dass es Texte auch in anderen Sprachen anzeigen kann. Problematisch hierbei ist, dass meist a priori unbekannt ist, welche Sprachen dies sein werden. Der Endbenutzer muss daher in der Lage sein, die jeweilige Sprache zur Laufzeit angeben zu können. Dieses Problem ist ein typischer Anwendungsbereich der Internationalisierung. Der internationalisierte Code, der keinerlei hart verdrahtete Texte mehr beinhaltet, lautet hierzu folgendermaßen:

code 

import java.util.*;
public class I18NBeispiel {

    static public void main(String[] args) {

      String sprache;
      String land;
      if (args.length != 2) {

        sprache = new String("en");
        land = new String("US");

      } else {

        sprache = new String(args[0]);
        land = new String(args[1]);

      }
      Locale currentLocale;
      ResourceBundle nachrichten;
      currentLocale = new Locale(sprache, land);
      nachrichten = ResourceBundle.getBundle("MessagesBundle",curren tLocale;
      System.out.println(nachrichten.getString("einlei tung"));
      System.out.println(nachrichten.getString("javaTe xt"));

    }

}

Das internationalisierte Programm ist flexibel, da es dem Endbenutzer die Möglichkeit einräumt, seine Sprache und sein Land in der Kommandozeile anzugeben. In den folgenden Beispielen werden die Texte erst auf französisch (der Sprach-Code für französisch ist fr, der Landes-Code ist FR für France) und dann in englischer Sprache (der Sprach-Code für englisch ist en, der Landes-Code ist US für United States) angezeigt.

code 

Aufruf: java I18NBeispiel fr FR

Ausgabe: Allo.

    Bienvenue en Java.

code 

Aufruf: java I18NBeispiel en US

Ausgabe: Hello.

    Welcome in Java.

Betrachtet man den internationalisierten Code näher, so bemerkt man, dass die vorher fest verdrahteten deutschen Texte verschwunden sind. Das Programm ist nun aus den folgenden zwei Gründen weltweit ausführbar: Erstens sind keine Texte fest im Code integriert und zweitens wird der Sprach-Code zur Laufzeit angegeben. Eine erneute Übersetzung ist zur Lokalisierung nicht erforderlich; das Programm ist bereits international einsetzbar.

Eine wichtige Frage ist nun, wohin die Texte, die fest in das Programm integriert waren, verschoben worden sind. Die hierzu notwendigen Schritte werden im Folgenden beschrieben:

  • Erzeugung einer Eigenschaftendatei (sog. Properties File)
    Ein Properties File, das in einem reinen Textformat mit einem beliebigen Texteditor erzeugt wird, speichert Informationen über Charakteristika eines Programms oder einer Umgebung.
    Im Beispiel speichern die Properties Files die Übersetzungen der Texte, die angezeigt werden sollen. Standardmäßig benennt man das Properties File mit
    MessagesBundle.properties und fügt die folgenden Zeilen ein:

code 

einleitung = Hallo
javaText = Willkommen in Java!

    Nachdem die Texte in einem Properties File angelegt sind, kann dieses in verschiedene Sprachen übersetzt werden. Änderungen des Quellcodes sind hierzu nicht erforderlich. Ein Französisch-Übersetzer würde bspw. ein Properties File MessagesBundle_fr_FR.properties erzeugen, das folgende Zeilen enthält:

code 

einleitung = Allo
javaText = Bienvenue en Java!

    Hierbei sollte beachtet werden, dass die Texte rechts der Gleichheitszeichen übersetzt wurden, nicht aber die Bezeichner auf der linken Seite. Diese Schlüssel dürfen nicht verändert werden, da sie vom Programm referenziert werden, wenn der übersetzte Text geladen wird. Wichtig ist weiterhin der Name des Properties Files. Der Name der Datei MessagesBundle_fr_FR.properties beinhaltet den Sprach-Code fr und den Landes-Code FR. Diese Codes werden verwendet, wenn ein Locale-Objekt angelegt wird.

  • Definition der Locale
    Ein Locale-Objekt identifiziert eine bestimmte Sprache und ein Land. Die folgende Anweisung definiert eine Locale mit der Sprache Französisch und dem Land Frankreich:

code 

aLocale = new Locale("fr","FR");

    Das vorgeschlagene Programm arbeitet flexibel, da es anstelle fest integrierter Sprach- und Landes-Codes Eingaben aus der Kommandozeile zur Laufzeit akzeptiert:

code 

String sprache = new String(args[0]);
String land = new String(args[1]);
currentLocale = new Locale(sprache, land);

    Locale-Objekte haben lediglich identifizierende Wirkung. Nach der Definition einer Locale wird diese an andere Objekte übergeben, die Aufgaben wahrnehmen, wie bspw. die Formatierung von Datumsangaben oder Währungen. Diese Objekte werden dann auch als Locale-sensitiv bezeichnet, da ihr Verhalten in Abhängigkeit von der Locale variiert. Das im Folgenden beschriebene ResourceBundle ist ein Beispiel eines Locale-sensitiven Objekts.

  • Erzeugung eines ResourceBundles
    ResourceBundle-Objekte beinhalten Locale-spezifische Objekte und werden vor allem dazu verwendet, Locale-sensitive Daten, wie bspw. zu übersetzender Text, zu isolieren. Im Beispiel greift das ResourceBundle-Objekt auf die Properties Files zu, die die anzuzeigenden Texte enthalten. Ein ResourceBundle-Objekt wird folgendermaßen erzeugt:

code 

nachricht = ResourceBundle.getBundle("MessagesBundle",currentLocale) ;

    Die Argumente, die an die getBundle-Methode übergeben werden, identifizieren die Properties Files, auf die anschließend zugegriffen wird. Das erste Argument, in diesem Fall MessagesBundle, bezeichnet hierbei die Familie der Properties Files.
    Die Locale, das zweite Argument der
    getBundle-Methode, spezifiziert, welche der MessagesBundle-Dateien ausgewählt werden soll. In dem Moment, in dem die Locale erzeugt wird, wird sowohl der Sprach- als auch der Landes-Code an deren Konstruktor übergeben. Hierbei ist zu beachten, dass im Namen des Properties Files der Sprach- und Landes-Code dem MessagesBundle-Objekt folgen.

  • Einladen des Textes aus dem ResourceBundle
    Properties Files beinhalten Paare aus Schlüssel und dazugehörigem Wert. Die Werte bestehen hierbei aus dem übersetzten Text, den das Programm anzeigen soll. Die Schlüssel werden dann angegeben, wenn die übersetzten Texte aus dem
    ResourceBundle-Objekt mittels der getString-Methode geladen werden. Um bspw. den Text zu laden, der durch den Schlüssel einleitung identifiziert wird, muss die getString-Methode folgendermaßen aufgerufen werden:

code 

String text1 = nachrichten.getString("einleitung");

  • Das Beispiel verwendet hierbei den Schlüssel einleitung, da dieser den Inhalt des Textes wiedergibt. An dieser Stelle kann aber auch ein beliebiger anderer Text verwendet werden. Der Schlüssel muss allerdings im Programm fest verdrahtet und auch in den Properties Files enthalten sein. Anderenfalls kann die Methode getString die Texte nicht auffinden.

Vor der detaillierten Erklärung der weiterführenden Internationalisierungskonzepte sei kurz auf Aspekte hingewiesen, die im Kontext der Internationalisierung nicht zu vernachlässigen sind. Viele Programme sind anfangs nicht internationalisiert (wenn sie zum ersten Mal geschrieben werden). Zur Umwandlung in eine internationalisierte Version sind die folgenden Gesichtspunkte zu beachten:

  • Identifikation kulturabhängiger Daten
    Nachrichten in Textform sind die offensichtlichste Form von Daten, die von Kultur zu Kultur variieren. Es existieren aber noch weitere Daten, die von einer Region oder Sprache abhängig sind. Die folgende Liste zeigt einige wichtige Beispiele:
    • Texte in Komponenten von Benutzeroberflächen
    • Online-Hilfen
    • Audiodateien
    • Grafiken
    • Icons
    • Datum und Zeit
    • Zahlen und Währungen
    • Maßeinheiten
  • Isolierung von übersetzbarem Text in ResourceBundles
    Übersetzungen sind stets kostenintensiv. Derartige Kosten können aber reduziert werden, wenn zu übersetzender Text in
    ResourceBundle-Objekten separiert wird. Derartige Texte sind bspw. Statusnachrichten, Fehlermeldungen oder auch Einträge in Benutzeroberflächen. Es ist zu bedenken, dass alle Vorkommen fest integrierter Texte, die dem Endbenutzer gezeigt werden, gefunden und ausgelagert werden müssen.
  • Verarbeitung von Verbundnachrichten
    Verbundnachrichten sind durch variable Daten gekennzeichnet. Im Beispiel „Ich esse 4 Scheiben Brot" ist eine Übersetzung dann schwierig, wenn die Zahl der Brotscheiben variabel ist, da die Position der Zahl nicht in allen Sprachen die gleiche ist. Verbundnachrichten sind daher weitestgehend zu vermeiden. Techniken, die angewendet werden sollten, wenn eine derartige Nachricht unvermeidbar ist, sind im Folgenden angegeben.
  • Formatierung von Zahlen und Währungen
    Wenn eine Anwendung Zahlen und Währungen anzeigt, müssen diese in einer Art und Weise formatiert werden, die unabhängig von einer Localen ist.
  • Formatierung von Datumsangaben und Zeiten
    Auch Datumsangaben und Zeiten variieren mit der Region und Sprache. Hierzu gilt das bereits vorher angeführte.
  • Geeignete Vergleiche von Zeichenketten
    Wenn Text sortiert oder durchsucht wird, müssen oft Zeichenketten verglichen werden. Es sollte darauf geachtet werden, dass anzuzeigender Text nicht mit den Methoden der
    String-Klasse verglichen wird. Die Methoden String.equals und String.compareTo führen bspw. binäre Vergleiche durch, die in einigen Sprachen wirkungslos sind. Anstelle dessen sollte bspw. die Collator-Klasse verwendet werden.
  • Konvertierung von Text, der nicht als Unicode vorliegt
    Zeichen werden in Java in Unicode kodiert. Eine Anwendung, die Text verwendet, der nicht als Unicode vorliegt, sollte daher in Unicode übersetzt werden.

Im Folgenden werden die Eigenschaften der Internationalisierung im Detail erläutert.


SPNavRight SPNavRight SPNavRight
BuiltByNOF