Подтвердить что ты не робот

Интернационализация имени отображения валюты Java

Есть ли причина, по которой некоторые отображаемые имена отображаются на английском языке, несмотря на то, что локали не находятся на английском языке (т.е. не переведены).

Например: Язык: "ru" не переведено

Locale locale = new Locale("ru");
Currency curr = Currency.getInstance("USD");
System.out.println(curr.getDisplayName(locale));
// US Dollar

Язык: перевод "es"

Locale locale = new Locale("es");
Currency curr = Currency.getInstance("USD");
System.out.println(curr.getDisplayName(locale));
// dólar estadounidense

Это намеренно? Или Java не получил, чтобы перевести его? Или я делаю что-то неправильно?

Я попытался найти файлы, в которых эти переводы сохранены, но не смог их найти. Если бы кто-то мог указать мне на этот ресурс, это было бы полезно.

Спасибо.

4b9b3361

Ответ 1

Поставщики локальных услуг

Java использует расширяемый механизм для предоставления данных (таких как строки, форматировщики и т.д.), которые локализованы.

Классы могут реализовать LocaleServiceProvider как factoryлокальные данные. Множество классов в java.util и java.textполагайтесь на этих поставщиков для правильной работы с разными Localeделегируя им создание объектов.

Примеры поставщиков локальных услуг можно найти в пакете java.util.spi, который обычно используется для отображения текста или цифр таким образом, чтобы зависит от Locale. Он включает CurrencyNameProvider, который используется Currency при вызове Currency#getDisplayName.

Поиск реализации

В классах, желающих использовать определенный LocaleServiceProvider (например, CurrencyNamePovider), используйте LocaleServiceProviderPool, чтобы найти экземпляры поставщика, поддерживающего определенный язык.

LocaleServiceProviderPool сначала пытается использовать стандартную реализацию, включенную в JRE. Если он не найден, он полагается на простой механизм интерфейса поставщика услуг (SPI) в Java и использует ServiceLoader 1 чтобы попытаться найти реализации, предоставляемые сторонними библиотеками.

Это то, что написано в учебнике о Locale:

Эти методы сначала проверяют, поддерживает ли среда выполнения Java запрошенную локаль; если это так, они используют эту поддержку. В противном случае методы вызывают методы getAvailableLocales() установленных поставщиков для соответствующего интерфейса, чтобы найти поставщика, который поддерживает запрошенный язык.

Стандартные реализации поставщиков, поставляемых с JRE, можно найти в пакете sun.util.locale.provider. Он сложный, но он по сути получает данные из jar localedata.jar. В Oracle JDK он находится в java_home/jre/lib/ext/localedata.jar. Если вы перечислите файлы, находящиеся в этой банке, и проверьте файлы в sun.util.resources.es и в sun.util.resources.ru, вы увидите, что для испанского языка существует больше имен валют, чем для русского.

Вот файлы для OpenJDK: Russian vs Испанский.

Что делать, если он вообще не определен

Локали организованы в иерархии. Например, конкретный регион страны может иметь локаль, которая отражает некоторые локальные различия с местностью страны. Если данные не найдены для Locale, LocaleServiceProviderPool попытается использовать родительский язык Locale.

Корень дерева локалей в основном представляет собой "резервную" вымышленную локаль, которая предоставляет значения по умолчанию для всех локализованных данных.

Что, вероятно, происходит, когда вы запрашиваете отображаемое имя USD на русском языке.

расширяемость

Любая программа может предоставить дополнительную информацию о локали. Им нужно определить поставщика услуг 1 создав файл метаданных и реализуя CurrencyNameProvider. Вы можете заполнить отсутствующие локализованные данные в своей собственной банке.

Заключение

Или Java не получил, чтобы перевести его?

Это в значительной степени.

Или я делаю что-то неправильно?

Нет, вы можете либо полагаться на значения по умолчанию, либо сами предоставлять локализованные данные.


1ServiceLoader найдет их, попросив загрузчика классов загрузить ресурс META-INF/services/java.text.spi.DateFormatProvider. Если такой файл найден, он должен иметь в нем конкретное имя класса реализации. Затем он пытается создать экземпляр его через загрузчик классов.