NumberFormat.getCurrencyInstance: примеры (JAVA)
NumberFormat.getCurrencyInstance: NumberFormatОбщее описание
Метод NumberFormat.getCurrencyInstance из пакета java.text создает объект форматирования чисел, настроенный для представления денежных сумм в соответствии с локалью. Доступны две перегрузки: без аргументов и с аргументом Locale. Первая версия возвращает формат для текущей системной локали, вторая - для указанной.
Возвращаемый тип: NumberFormat. На большинстве платформ экземпляр будет подклассом DecimalFormat, что позволяет дополнительно настраивать шаблон, символы и поведение парсинга.
Ключевые правила работы:
- Локаль определяет символ валюты, разделители групп и десятичный разделитель.
- По умолчанию число знаков после запятой соответствует
Currency.getDefaultFractionDigits()для валюты локали. - Формат не является потокобезопасным: один экземпляр не должен использоваться одновременно из нескольких потоков без синхронизации.
Аргументы и возвращаемые значения:
getCurrencyInstance()- нет аргументов. ВозвращаетNumberFormatдля системной локали.getCurrencyInstance(Locale locale)- аргументlocaleтипаjava.util.Locale. Еслиlocaleравенnull, возможенNullPointerException(в зависимости от реализации JVM).- Возвращаемый объект предоставляет методы
format(Number)для форматирования иparse(String)для разбора. Для тонкой настройки можно применять методыsetCurrency(Currency),setMinimumFractionDigits,setMaximumFractionDigits,setGroupingUsedи при необходимости приводить кDecimalFormatдля доступа к дополнительным настройкам.
Замечание:
Для финансовых вычислений предпочтительнее хранить деньги в типах с фиксированной точкой (например, BigDecimal или специализированных API), а NumberFormat использовать только для отображения и разбора представлений.
Простые примеры
Пример 1: Форматирование по явной локали
import java.text.NumberFormat;
import java.util.Locale;
public class Example1 {
public static void main(String[] args) {
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(nf.format(12345.67));
}
}
$12,345.67
Пример 2: Форматирование для Франции
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.FRANCE);
System.out.println(nf.format(12345.67));
12 345,67 €
Пример 3: Изменение валюты у возвращенного формата
import java.text.NumberFormat;
import java.util.Currency;
import java.util.Locale;
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
nf.setCurrency(Currency.getInstance("JPY"));
System.out.println(nf.format(12345.67));
¥12,346
Пример 4: Разбор строки в число
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
try {
Number n = nf.parse("$1,234.56");
System.out.println(n); // будет Double или Long в зависимости от реализации
} catch (ParseException e) {
e.printStackTrace();
}
1234.56
Аналоги в Java
- DecimalFormat - более низкоуровневый класс, дающий доступ к шаблонам,
DecimalFormatSymbolsи дополнительным настройкам. Предпочтителен, когда требуется точная настройка шаблона отображения. - String.format / Formatter - удобен для простого форматирования чисел с учетом локали (через
Locale), но не предоставляет автоматической подстановки символа валюты; символ добавляется вручную. - JSR 354 (javax.money) - спецификация и реализация для представления денежных величин и операций над ними. Предпочтительна для бизнес-логики и вычислений с валютами, так как обеспечивает типобезопасность и семантику денег.
Выбор зависит от задач: для отображения и простого разбора подойдут NumberFormat и DecimalFormat. Для финансовых вычислений лучше применять библиотеки, реализующие денежную модель (JSR 354 или собственные классы на основе BigDecimal).
Аналоги в других языках
JavaScript
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(12345.67)
"$12,345.67"
Python
# с библиотекой Babel
from babel.numbers import format_currency
print(format_currency(12345.67, 'USD', locale='en_US'))
"$12,345.67"
PHP
// с расширением intl
$fmt = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(12345.67, 'USD');
"$12,345.67"
C#
using System.Globalization;
decimal v = 12345.67m;
Console.WriteLine(v.ToString("C", CultureInfo.GetCultureInfo("en-US")));
"$12,345.67"
Go
import "golang.org/x/text/message"
p := message.NewPrinter(message.Language("en"))
p.Printf("%s", "$12,345.67") // стандартной кросс-локаль поддержки валют нет
"$12,345.67"
SQL (PostgreSQL)
SELECT to_char(12345.67, 'LFM9,999,990.00');
"$12,345.67" (при установленной локали и валютном символе)
Отличие от Java: многие языки предлагают встроенный интернационализированный форматер (JS, PHP intl, Babel в Python), тогда как Java использует NumberFormat и дополнительную спецификацию JSR 354 для бизнес-логики с валютами. В Java при необходимости тонкой настройки часто требуется приведение к DecimalFormat.
Типичные проблемы и ошибки
- NullPointerException: вызов
getCurrencyInstance(null)может привести к NPE. Проверка аргументаLocaleрешает проблему. - ClassCastException: предположение, что возвращаемый
NumberFormatвсегда являетсяDecimalFormat. Без проверкиinstanceofприведение может завершиться ошибкой на некоторых реализациях. - Потокобезопасность: использование одного экземпляра в нескольких потоках без синхронизации приводит к некорректным результатам.
- Неожиданное округление: некоторые валюты (например, JPY) имеют 0 дробных знаков. Подстановка другой валюты может изменить число дробных знаков и привести к округлению.
- Проблемы при разборе строк: наличие пробелов, неразрывных пробелов или локально-позиционированных символов валюты может мешать
parse. В таких случаях предварительная нормализация строки облегчит разбор.
Пример ошибки приведения
NumberFormat nf = NumberFormat.getCurrencyInstance(new Locale("ar","SA"));
DecimalFormat df = (DecimalFormat) nf; // может выбросить ClassCastException в нестандартной реализации
ClassCastException: java.text.SomeOtherFormat cannot be cast to java.text.DecimalFormat
Изменения и заметки по версиям
Сам API NumberFormat.getCurrencyInstance в языке Java остается стабилен на протяжении многих версий. В современных релизах JVM изменений в контракте этого метода не было. Основные изменения в экосистеме относятся к появлению и развитию JSR 354 (Money and Currency API), предлагающего специализированные типы для денег и форматирования с расширенными возможностями. При миграции на новые версии платформы следует обратить внимание на обновления локализационных данных в JDK (символы валют, правила группировки), которые влияют на вывод.
Расширенные и редкие примеры
1) Принудительная настройка символа валюты
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.GERMANY);
if (nf instanceof DecimalFormat) {
DecimalFormat df = (DecimalFormat) nf;
DecimalFormatSymbols sym = df.getDecimalFormatSymbols();
sym.setCurrencySymbol("EUR*");
df.setDecimalFormatSymbols(sym);
System.out.println(df.format(1234.5));
}
1.234,50 EUR*
2) Форматирование с выключенной группировкой
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
nf.setGroupingUsed(false);
System.out.println(nf.format(1234567.89));
$1234567.89
3) Задание другой валюты и влияние на количество дробных знаков
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
// по умолчанию USD -> 2 дробных знака
nf.setCurrency(java.util.Currency.getInstance("JPY"));
System.out.println(nf.format(1234.56)); // JPY имеет 0 дробных знаков
¥1,235
4) Парсинг в BigDecimal (при наличии DecimalFormat#setParseBigDecimal)
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
if (nf instanceof DecimalFormat) {
DecimalFormat df = (DecimalFormat) nf;
df.setParseBigDecimal(true); // доступно в DecimalFormat
try {
Object parsed = df.parse("$1234.56");
if (parsed instanceof BigDecimal) {
BigDecimal bd = (BigDecimal) parsed;
System.out.println(bd);
} else {
System.out.println(parsed);
}
} catch (Exception e) {
e.printStackTrace();
}
}
1234.56
5) Комбинация с JSR 354 (пример концептуальный)
// Концептуальный пример: использовать javax.money для точной работы с валютой,
// а NumberFormat для отображения при необходимости.
// Money money = Monetary.getDefaultAmountFactory().setCurrency("USD").setNumber( new BigDecimal("1234.56") ).create();
// Для форматирования можно получить строку через MonetaryAmountFormat из реализации JSR 354.
(Зависит от реализации JSR 354, вывод: "$1,234.56")
В продвинутых сценариях рекомендуется проверять тип возвращаемого формата, явно настраивать символы и поведение округления и применять специализированные денежные библиотеки для логики расчетов.
джава NumberFormat.getCurrencyInstance function comments
- джава NumberFormat.getCurrencyInstance - аргументы и возвращаемое значение
- Функция java NumberFormat.getCurrencyInstance - описание
- NumberFormat.getCurrencyInstance - примеры
- NumberFormat.getCurrencyInstance - похожие методы на java
- NumberFormat.getCurrencyInstance на javascript, c#, python, php
- NumberFormat.getCurrencyInstance изменения java
- Примеры NumberFormat.getCurrencyInstance на джава