NumberFormat.getInstance: примеры (JAVA)
NumberFormat.getInstance: NumberFormatОписание NumberFormat.getInstance
Метод NumberFormat.getInstance из пакета java.text предоставляет готовый форматтер для представления и разбора чисел с учётом локали. Это статический фабричный метод, возвращающий объект типа NumberFormat. На практике конкретной реализацией чаще всего оказывается java.text.DecimalFormat, имеющий дополнительные возможности по настройке.
Когда применяется
- Форматирование отображаемых чисел с локальными разделителями десятичных и группировочных разрядов.
- Разбор строк в числа с учётом локали (например, десятичная запятая в некоторых регионах).
- Подготовка чисел для отображения пользователю с учётом культурных особенностей.
Сигнатуры и аргументы
public static NumberFormat getInstance()- возвращает форматтер для чисел по умолчанию, использующий текущую локаль (Locale.getDefault()).public static NumberFormat getInstance(Locale inLocale)- возвращает форматтер, соответствующий указанной локалиinLocale. Если переданnull, применяется локаль по умолчанию.
Возвращаемое значение
- Объект
NumberFormat. Он может форматировать методомformat(Number)и разбирать методомparse(String). - Возвращаемый объект часто является
DecimalFormat, что позволяет дополнительно настраивать шаблоны, символы и режимы округления.
Особенности поведения
- Экземпляры не являются потокобезопасными. Повторное использование одного объекта в нескольких потоках требует синхронизации или создания отдельного экземпляра для каждого потока.
- Метод
parseвозвращаетNumber. Конкретный тип может бытьLong,Double,BigDecimal(при соответствующей настройке) и т. д. - Некоторые настройки присутствуют в базовом
NumberFormat(например,setGroupingUsed,setMaximumFractionDigits). Дополнительные настройки доступны уDecimalFormat(например,setDecimalFormatSymbols,applyPattern,setRoundingMode,setParseBigDecimal).
Ограничения
- Не предоставляет напрямую форматирования валюты или процентов; для этих задач существуют специализированные фабрики:
getCurrencyInstanceиgetPercentInstance. Однако результатgetInstanceможно кастовать кDecimalFormatи применять шаблоны.
Короткие примеры использования
1. Базовое форматирование и разбор
import java.text.NumberFormat;
import java.util.Locale;
NumberFormat nf = NumberFormat.getInstance();
String s = nf.format(12345.678);
Number n = nf.parse("12,345.678");
System.out.println(s);
System.out.println(n + " (" + n.getClass().getSimpleName() + ")");
12,345.678 12345.678 (Double)
2. Формат для конкретной локали (Франция: десятичная запятая)
NumberFormat nfFr = NumberFormat.getInstance(Locale.FRANCE);
String sFr = nfFr.format(12345.678);
Number p = nfFr.parse("12 345,678"); // NBSP в группировке
System.out.println(sFr);
System.out.println(p);
12 345,678 12345.678
3. Отключение группировки и ограничение дробных знаков
NumberFormat nfNoGroup = NumberFormat.getInstance();
nfNoGroup.setGroupingUsed(false);
nfNoGroup.setMaximumFractionDigits(2);
System.out.println(nfNoGroup.format(12345.6789));
12345.68
4. Приведение к DecimalFormat для доступа к дополнительным опциям
import java.text.DecimalFormat;
import java.text.NumberFormat;
NumberFormat nf = NumberFormat.getInstance();
if (nf instanceof DecimalFormat) {
DecimalFormat df = (DecimalFormat) nf;
df.applyPattern("###,##0.000");
System.out.println(df.format(12345.6789));
}
12,345.679
Похожие средства в Java
В стандартной библиотеке имеются близкие по назначению фабрики и классы:
- NumberFormat.getIntegerInstance(Locale)
- Предназначен для форматирования целых чисел. Дробная часть отбрасывается при форматировании и разборе с учётом настроек.
- NumberFormat.getCurrencyInstance(Locale)
- Возвращает форматтер с локализованным символом валюты и правилами отображения. Предпочтителен для вывода цен.
- NumberFormat.getPercentInstance(Locale)
- Упрощает вывод процентов, автоматически умножая значение на 100 и добавляя знак процента.
- DecimalFormat
- Даёт гибкость настройки шаблонов, символов и режима округления. Используется, когда требуются специфические шаблоны.
Выбор зависит от задачи: для локализованного отображения чисел подойдёт getInstance, для валюты - getCurrencyInstance, для целых чисел - getIntegerInstance. Для детальной настройки шаблонов предпочтительнее использовать DecimalFormat.
Аналоги в других языках и отличия
JavaScript (Intl.NumberFormat)
const nf = new Intl.NumberFormat('fr-FR');
console.log(nf.format(12345.678));
12 345,678
Отличие: API ориентирован на форматирование только; разбор строк в числа требует дополнительных библиотек.
Python (locale и babel)
import locale
locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')
print(locale.format_string("%0.3f", 12345.678, grouping=True))
12 345,678
Python stdlib обеспечивает простую локализацию, но для продвинутой работы часто используется библиотека babel.numbers, схожая с Java по возможностям.
PHP (number_format и NumberFormatter)
echo number_format(12345.678, 3, '.', ',');
// или с Intl
$fmt = new NumberFormatter('fr_FR', NumberFormatter::DECIMAL);
echo $fmt->format(12345.678);
12,345.678 12 345,678
Отличие: procedural-функция number_format проста, а NumberFormatter из ext-intl предоставляет поведение, близкое к Java.
C# (.NET) (NumberFormatInfo, CultureInfo)
using System;
using System.Globalization;
var ci = new CultureInfo("fr-FR");
Console.WriteLine((12345.678).ToString("N3", ci));
12 345,678
Отличие: .NET имеет богатую поддержку через форматные строки и объекты CultureInfo, аналогично Java по возможностям.
Go (golang.org/x/text/message)
import (
"fmt"
"golang.org/x/text/language"
"golang.org/x/text/message"
)
p := message.NewPrinter(language.French)
p.Printf("%v\n", 12345.678)
12 345,678
Отличие: стандартный пакет fmt не учитывает локаль, для локализованного вывода обычно используется внешний пакет.
Kotlin
import java.text.NumberFormat
import java.util.Locale
val nf = NumberFormat.getInstance(Locale.FRANCE)
println(nf.format(12345.678))
12 345,678
Kotlin работает с тем же API, что и Java, поэтому поведение совпадает.
SQL (пример PostgreSQL)
SELECT to_char(12345.678, 'FM9G999D999') AS formatted;
12,345.678
Отличие: SQL использует собственные функции формата; локаль влияет на разделители через настройки базы.
Типичные ошибки и примеры
1. Ошибка: ожидание потокобезопасности
// Небезопасный пример
private static final NumberFormat NF = NumberFormat.getInstance();
// В многопоточном приложении разные потоки одновременно вызывают NF.format(...)
Возможны некорректные результаты и состояние гонки. Решение: создавать экземпляр на поток или синхронизировать обращения.
2. Ошибка: неверный парсинг из строки с другой локалью
NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
Number n = nf.parse("12,345.678");
System.out.println(n);
12345 (или ParseException в зависимости от входа) // Входная строка не соответствует ожидаемому формату локали, поэтому результат может быть неожиданным.
3. Ошибка: приведение без проверки типа
NumberFormat nf = NumberFormat.getInstance();
NumberFormat dec = nf; // возможно DecimalFormat
DecimalFormat df = (DecimalFormat) dec; // если реализация другая, возможен ClassCastException
ClassCastException при другой реализации. Рекомендуется проверять instanceof перед приведением.
4. Ошибка: не обрабатывается ParseException
NumberFormat nf = NumberFormat.getInstance();
Number n = nf.parse("abc"); // вызывает ParseException
java.text.ParseException: Unparseable number: "abc" // ParseException требуется перехватывать или обрабатывать.
Изменения и эволюция
Сам метод NumberFormat.getInstance в API Java остаётся стабильным. В последних версиях Java происходили улучшения в поддержке локалей и поставщиках данных локализации (CLDR), что повлияло на отображение символов и шаблонов в разных локалях. Кроме того, в более новых релизах появились дополнительные фабрики для компактного форматирования чисел (getCompactNumberInstance) и расширенные возможности у DecimalFormat (новые символы, улучшенная поддержка округления). Конкретные изменения зависят от версии JDK и выбранного провайдера локалей.
Продвинутые и редко используемые примеры
1. Разбор в BigDecimal с сохранением точности
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.math.BigDecimal;
NumberFormat nf = NumberFormat.getInstance();
if (nf instanceof DecimalFormat) {
DecimalFormat df = (DecimalFormat) nf;
df.setParseBigDecimal(true);
Number n = df.parse("12345.678");
System.out.println(n.getClass().getName() + " -> " + n);
}
java.math.BigDecimal -> 12345.678
2. Кастомизация символов (замена разделителя)
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
symbols.setDecimalSeparator(',');
symbols.setGroupingSeparator('\u00A0'); // неразрывный пробел
df.setDecimalFormatSymbols(symbols);
System.out.println(df.format(12345.678));
12 345,678
3. Установка режима округления
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
df.setMaximumFractionDigits(2);
df.setRoundingMode(RoundingMode.DOWN);
System.out.println(df.format(1.239));
System.out.println(df.format(1.235));
1.23 1.23
4. Частичный разбор с ParsePosition
import java.text.NumberFormat;
import java.text.ParsePosition;
NumberFormat nf = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
Number n = nf.parse("123abc", pos);
System.out.println(n + ", parsed up to index " + pos.getIndex());
123, parsed up to index 3
5. Использование в многопоточном контексте через ThreadLocal
import java.text.NumberFormat;
private static final ThreadLocal NF_LOCAL = ThreadLocal.withInitial(NumberFormat::getInstance);
// Внутри потока
NumberFormat nf = NF_LOCAL.get();
System.out.println(nf.format(12345.678));
12,345.678 (в зависимости от локали)
6. Компоновка шаблонов для показа тысячных и малого формата
import java.text.DecimalFormat;
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
df.applyPattern("#,##0.###' 'units");
System.out.println(df.format(12345.678));
12,345.678 units
7. Форматирование для CSV: отключение группировки и фиксированная точность
NumberFormat nf = NumberFormat.getInstance();
nf.setGroupingUsed(false);
nf.setMaximumFractionDigits(6);
System.out.println(nf.format(12345.6));
12345.6
8. Сравнение результатов для разных локалей
System.out.println(NumberFormat.getInstance(Locale.US).format(12345.678));
System.out.println(NumberFormat.getInstance(Locale.GERMANY).format(12345.678));
System.out.println(NumberFormat.getInstance(Locale.JAPAN).format(12345.678));
12,345.678 12.345,678 12345.678
джава NumberFormat.getInstance function comments
- джава NumberFormat.getInstance - аргументы и возвращаемое значение
- Функция java NumberFormat.getInstance - описание
- NumberFormat.getInstance - примеры
- NumberFormat.getInstance - похожие методы на java
- NumberFormat.getInstance на javascript, c#, python, php
- NumberFormat.getInstance изменения java
- Примеры NumberFormat.getInstance на джава