Format: примеры (JAVA)
format(DateTimeFormatter formatter): StringОбщее описание метода String.format и класса Formatter
В Java для форматирования строк часто применяется статический метод String.format и близкий по семантике класс java.util.Formatter. Основные сигнатуры метода:
public static String format(String format, Object... args)public static String format(Locale l, String format, Object... args)
Также форматирование может выполняться методами PrintStream.printf и Formatter.format, которые используют тот же синтаксис спецификаторов.
Формат спецификатора имеет общий вид:
%[argument_index$][flags][width][.precision][t]conversion
Ключевые компоненты:
- argument_index$ - номер аргумента (1-based), например
%2$sиспользует второй аргумент. - flags - набор опций:
-(выравнивание влево),+(показать знак),0(дополнение нулями),,(группировка тысяч),((скобки для отрицательных),#(альтернативный формат),(пробел при положительном числе),<(повтор предыдущего аргумента). - width - минимальная ширина поля (целое число).
- .precision - точность: количество знаков после запятой для плавающих, максимальная длина для строк.
- t - префикс для форматирования дат/времени; далее указывается символ преобразования (например,
tF,tT,tYи т.д.). - conversion - тип преобразования:
s(строка),d(целое десятичное),o(восьмеричное),x(шестнадцатеричное),f(десятичное с плавающей точкой),e(научная нотация),g(обобщённый формат),b(булево),c(символ),a(шестнадцатеричный формат плавающей),n(разделитель строки),%(символ процента). Для дат/времени используются буквы послеt/T(например,tY,tm,).
Возвращаемые значения и поведение:
String.formatвозвращает новую отформатированную строку.Formatter.formatвозвращает сам объектFormatterи позволяет накапливать вывод в привязанномAppendable.PrintStream.printfвозвращает тот жеPrintStream, на который производится вывод.
Исключения при ошибках формата:
IllegalFormatExceptionи его подклассы, напримерMissingFormatArgumentException,UnknownFormatConversionException,IllegalFormatConversionException,IllegalFormatWidthExceptionи др.
Короткие примеры использования
Ниже приведены простые сценарии с кодом и результатом.
Пример 1. Базовое форматирование
String s = String.format("Hello, %s!", "World");
System.out.println(s);
Hello, World!
Пример 2. Ширина и выравнивание
System.out.println(String.format("|%10s|", "x"));
System.out.println(String.format("|%-10s|", "x"));
| x| |x |
Пример 3. Числа: группировка и знаки
System.out.println(String.format(Locale.US, "%+,d", 1234567));
System.out.println(String.format("%05d", 42));
+1,234,567 00042
Пример 4. Плавающая точка: точность
System.out.println(String.format("%.2f", Math.PI));
3.14
Пример 5. Перестановка аргументов (argument_index)
System.out.println(String.format("%2$s = %1$d", 10, "ten"));
ten = 10
Пример 6. Дата и время
System.out.println(String.format("Today: %1$td.%1$tm.%1$tY", new java.util.Date()));
Today: 21.04.2026
Пример 7. Символ процента
System.out.println(String.format("Progress: %.0f%%", 85.5));
Progress: 86%
Похожая функциональность в Java и особенности
- java.util.Formatter - низкоуровневый класс для форматирования с тем же синтаксисом; полезен при накоплении форматированного текста в
Appendable. - PrintStream.printf / PrintWriter.printf - вывод формата напрямую в поток, возвращают поток для цепочек вызовов.
- MessageFormat - предназначен для интернационализированных сообщений и шаблонов с параметрами; удобнее при локализации и при необходимости автоподстановки мест (не использует %-спецификаторы).
- java.text.DecimalFormat - для детального форматирования чисел с шаблоном (пользовательские шаблоны группировки, десятичные разделители, префиксы/суффиксы).
- java.time.format.DateTimeFormatter - предпочтителен для форматирования объектов new Date/Time API (java.time) вместо %t-* спецификаторов.
Выбор между ними: String.format и Formatter удобны для быстрого %-стиля форматирования; MessageFormat и DateTimeFormatter рекомендуются для локализации и форматирования дат/чисел с гибким контролем.
Аналоги в других языках и отличия
PHP - sprintf / printf
echo sprintf("%s costs %.2f", "apple", 1.5);
apple costs 1.50
Синтаксис похож; отличие в поведении языковой локали для чисел и в типовой системе PHP.
JavaScript - шаблонные строки, util.format (Node.js) и Intl
// template literal
console.log(`${name} costs ${price.toFixed(2)}`);
// Node.js util.format
const util = require('util');
console.log(util.format('%s costs %d', 'apple', 2));
apple costs 2
В браузере нет встроенного sprintf; чаще используют шаблоны и Intl для локали.
Python - format и f-strings
print("{0} costs {1:.2f}".format('apple', 1.5))
print(f"apple costs {1.5:.2f}")
apple costs 1.50 apple costs 1.50
Форматирование в Python более гибкое и выразительное, f-strings компактнее.
SQL - FORMAT, TO_CHAR
-- SQL Server
SELECT FORMAT(1234567, 'N0');
-- Oracle
SELECT TO_CHAR(12345.678, 'FM99999.00') FROM dual;
1,234,567 12345.68
В SQL форматирование ориентировано на представление данных в результирующем наборе и зависит от СУБД.
C# - String.Format и интерполяция
Console.WriteLine(String.Format("{0} costs {1:0.00}", "apple", 1.5));
Console.WriteLine($"apple costs {1.5:0.00}");
apple costs 1.50 apple costs 1.50
Синтаксис C# использует фигурные скобки для плейсхолдеров и форматов, отличается от %-стиля Java.
Lua - string.format
print(string.format("%s costs %.2f", "apple", 1.5))
apple costs 1.50
Go - fmt.Sprintf
fmt.Println(fmt.Sprintf("%s costs %.2f", "apple", 1.5))
apple costs 1.50
Kotlin - String.format и шаблонные строки
println(String.format("%s costs %.2f", "apple", 1.5))
// или шаблоны с форматированием через %
println("${"apple"} costs ${"%.2f".format(1.5)}")
apple costs 1.50 apple costs 1.50
Основные отличия: синтаксис и локализация; в некоторых языках (Python, C#) форматирование более интегрировано в синтаксис, в Java используется %-стиль или отдельные API для локализации.
Типичные ошибки и примеры
1) Несоответствие типа спецификатора и аргумента
System.out.println(String.format("%d", "text"));
Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.String at java.base/java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4382) ... (stack trace)
2) Недостающий аргумент (MissingFormatArgumentException)
System.out.println(String.format("%s %s", "onlyOne"));
Exception in thread "main" java.util.MissingFormatArgumentException: Format specifier '%s'
3) Неверный символ преобразования
System.out.println(String.format("%q", 10));
Exception in thread "main" java.util.UnknownFormatConversionException: Conversion = 'q'
4) Null в качестве строки формата
String.format(null, 1);
Exception in thread "main" java.lang.NullPointerException
5) Локализация: неожиданный разделитель числа
System.out.println(String.format(Locale.GERMANY, "%,.2f", 1234.56));
1.234,56
Ожидаемый результат может отличаться в зависимости от переданной Locale.
Изменения и замечания по версиям Java
Механизм форматирования (класс Formatter и метод String.format) появился в Java 5. В последующих версиях спецификаторы и поведение оставались стабильными. В более новых релизах происходило улучшение производительности и исправление багов, но синтаксис остаётся совместимым назад.
Рекомендация: при работе с датами и новыми классами времени (java.time) предпочтительнее DateTimeFormatter вместо устаревших форматов через %t, если требуется гибкое форматирование и локализация.
Расширенные и редкие варианты использования
1) Повторное использование аргумента и реиспользование предыдущего значения (<)
System.out.println(String.format("First: %1$s, again: %1$s, previous: %
First: one, again: one, previous: one
2) Форматирование BigDecimal с точностью и локалью
java.math.BigDecimal bd = new java.math.BigDecimal("12345.6789");
System.out.println(String.format(Locale.FRANCE, "%,.2f", bd));
12 345,68
В примере используется неразрывный пробел в качестве разделителя тысяч в локали FR.
3) Использование Formatter с Appendable (накапливание вывода)
StringBuilder sb = new StringBuilder();
try (java.util.Formatter fmt = new java.util.Formatter(sb, Locale.US)) {
fmt.format("Name: %s, Age: %d", "Alice", 30);
}
System.out.println(sb.toString());
Name: Alice, Age: 30
4) Форматирование отрицательных чисел в скобках (flag '(')
System.out.println(String.format("%(,.2f", -12345.67));
(12,345.67)
5) Смешение %s и %t в сложных шаблонах
java.util.Date date = new java.util.Date(0); // epoch
System.out.println(String.format("At %1$tH:%1$tM on %1$tY-%1$tm-%1$td: %2$s", date, "event"));
At 03:00 on 1970-01-01: event
Вывод времени зависит от часовой зоны среды выполнения.
6) Динамическая ширина или точность через аргументы
System.out.println(String.format("%1$*2$s", 123, 6)); // некорректно
// Правильный способ: использовать индекс аргумента для ширины не предусмотрен в %-синтаксисе Java.
// Вместо этого строится формат динамически:
int width = 6;
System.out.println(String.format("%" + width + "d", 123));
123
7) Форматирование пользовательских объектов: toString и хеш
class P { public String toString(){ return "P"; } }
P p = new P();
System.out.println(String.format("Obj=%s, hash=%h", p, p));
Obj=P, hash=7e0b1f3d
8) Форматирование с учётом производительности
При частых операциях форматирования рекомендуется избегать лишних аллокаций: использовать один Formatter с переиспользуемым StringBuilder или специализированные API (например, StringBuilder.append) для простых конкатенаций.
9) Комбинация с локализованными ресурсами
java.util.ResourceBundle rb = java.util.ResourceBundle.getBundle("msg", Locale.FRANCE);
String tpl = rb.getString("balance"); // предположим: "Votre solde: %,.2f"
System.out.println(String.format(Locale.FRANCE, tpl, 12345.6));
Votre solde: 12 345,60
10) Обработка исключений форматирования в библиотеке
Рекомендуется отслеживать IllegalFormatException при парсинге динамически собираемых шаблонов и логировать шаблон вместе с аргументами для отладки.