String.format: примеры (JAVA)
String.format(String format, Object... args): StringОписание и синтаксис метода String.format
Метод String.format в Java формирует строку по шаблону форматирования. Доступны две перегрузки:
public static String format(String format, Object... args)public static String format(Locale l, String format, Object... args)
Метод возвращает новую строку, сформированную на основе шаблона format и аргументов args. Встроенный парсер поддерживает спецификаторы формата, рассчитанные на работу с числовыми, символьными, строковыми, шестнадцатеричными и дата/время преобразованиями, а также с некоторыми специальными символами.
Общий синтаксис спецификатора:
%[argument_index$][flags][width][.precision][t]conversion
Пояснения к частям спецификатора:
- argument_index$ - позиция аргумента (1-based), например
2$. - flags - набор модификаторов:
-(выравнивание влево),+(знак для чисел),0(дополнение нулями),,(группировка разрядов),((скобки для отрицательных),#(альтернативная форма),(пробел для положительных), и символ повтора аргумента<. - width - минимальная ширина вывода в символах; при необходимости добавляется заполнение.
- .precision - точность (для чисел с плавающей точкой количество знаков после запятой, для строк максимальная длина и т. п.).
- t - префикс для спецификаторов даты/времени; после него указывается форма, например
tF,tT,tdи др. - conversion - тип преобразования:
b,B- булево (false/null -> "false"),h,H- hashCode как шестнадцатеричное представление,s,S- строковое представление,c,C- символ,d- десятичное целое,o- восьмеричное целое,x,X- шестнадцатеричное целое,e,E,f,g,G- научный формат, фиксированный и общий формат для чисел с плавающей точкой,a,A- шестнадцатеричный формат для плавающей точки,t/T- дата и время (много подтипов),n- платформа-зависимый перевод строки,%- литерал процента.
Поведение зависит от локали при использовании перегрузки с Locale. Локаль влияет на разделитель дробной части, группировку разрядов и представление даты/времени. При несоответствии спецификатора и аргумента генерируются исключения группы IllegalFormatException. Если format равен null, будет выброшено NullPointerException.
Типичные исключения при форматировании: MissingFormatArgumentException, IllegalFormatConversionException, IllegalFormatWidthException и другие подтипы IllegalFormatException.
Короткие примеры использования
Несколько быстрых случаев применения с кодом и результатом.
Пример 1: базовое подстановочное форматирование
String s = String.format("Hello, %s!", "Alice");
System.out.println(s);
Hello, Alice!
Пример 2: целые числа с заполнением и знаком
String a = String.format("%+06d", 42);
System.out.println(a);
+00042
Пример 3: число с плавающей точкой и точностью
String b = String.format(Locale.US, "%.3f", 1.0/3);
System.out.println(b);
0.333
Пример 4: группировка разрядов
String c = String.format(Locale.US, "%,d", 1234567);
System.out.println(c);
1,234,567
Пример 5: шестнадцатеричный вывод и флаг #
String d = String.format("%#x", 255);
System.out.println(d);
0xff
Пример 6: форматирование даты
Date now = new java.util.Date();
String date = String.format(Locale.getDefault(), "%tF %tT", now, now);
System.out.println(date);
2026-04-24 12:34:56
Пример 7: повторное использование аргумента и позиция
String e = String.format("%2$s %1$s %
second first first
Пример 8: литерал процента и перевод строки
String f = String.format("Progress: %d%% %n", 75);
System.out.print(f);
Progress: 75%
Похожие возможности в Java и их особенности
В Java доступны другие средства форматирования строк, отличающиеся по назначению:
- java.util.Formatter - базовый класс, обеспечивающий те же спецификации, но с возможностью вывода в Appendable; удобен при форматировании в поток или StringBuilder.
- System.out.printf / System.out.format - обёртки, формирующие и сразу выводящие отформатированные данные на консоль; полезны для логирования и интерактивных приложений.
- java.text.MessageFormat - ориентирован на интернационализацию; лучше для составления сообщений с учетом правил языка, множества форматов и порядка аргументов при локализации.
- NumberFormat, DateFormat, DateTimeFormatter - специализированные парсеры и форматтеры для чисел и дат с поддержкой локали; предпочтительнее при сложных локализационных правилах.
Выбор зависит от задачи: для простых форматных строк удобен String.format, при международных сообщениях и изменяемом порядке аргументов предпочтительнее MessageFormat, для вывода в поток подходит Formatter.
Аналоги в других языках и ключевые отличия
Краткий обзор аналогичных функций в популярных языках с примерами.
PHP - sprintf
$s = sprintf("Hello, %s! %d%%", "Bob", 80);
echo $s;
Hello, Bob! 80%
JavaScript - шаблонные строки и util.format (Node.js)
// Шаблонные строки
let name = 'Eve';
let s = `Hello, ${name}!`;
console.log(s);
// Node.js util.format
const util = require('util');
console.log(util.format('Number: %d, Hex: %x', 42, 42));
Hello, Eve! Number: 42, Hex: 2a
Python - форматирование через format и f-строки
s = "Hello, {}! {:.2f}".format('Ann', 1.23456)
print(s)
# f-строка
name = 'Ann'
value = 1.23456
print(f"Hello, {name}! {value:.2f}")
Hello, Ann! 1.23 Hello, Ann! 1.23
SQL - функции форматирования зависят от СУБД
-- PostgreSQL
SELECT to_char(now(), 'YYYY-MM-DD HH24:MI:SS');
-- MySQL
SELECT FORMAT(1234567.89, 2);
2026-04-24 12:34:56 1,234,567.89
C# - string.Format и интерполяция
string s = string.Format("{0}, {1:000}", "Id", 5);
Console.WriteLine(s);
// Интерполяция
int x = 5;
Console.WriteLine($"Value: {x:D3}");
Id, 005 Value: 005
Lua - string.format
local s = string.format("%s: %.2f", "pi", 3.14159)
print(s)
pi: 3.14
Go - fmt.Sprintf
s := fmt.Sprintf("%s %d", "count", 10)
fmt.Println(s)
count 10
Kotlin - String.format и шаблоны строк
val s = String.format("Hello, %s!", "Kotlin")
println(s)
// Шаблонная строка
val name = "Kotlin"
println("Hello, $name!")
Hello, Kotlin! Hello, Kotlin!
Отличия от Java: синтаксис спецификаторов у языков часто схож с C-подобным, но локализация, поддерживаемые флаги и поведение с null/None/undefined различаются. В языках с интерполяцией (JS, Kotlin, C#) привычные случаи форматирования строк решаются проще с меньшим количеством спецификаторов, тогда как sprintf-подобные функции дают точный контроль над форматом.
Типичные ошибки и примеры исключений
Ниже перечислены распространённые ошибки при использовании String.format с примерами кода и результатами в виде исключений или неожиданных значений.
Ошибка 1: несовпадение спецификатора и типа аргумента
String s = String.format("%d", "not a number");
Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.String
Ошибка 2: недостаточно аргументов
String s = String.format("%s %s", "one");
Exception in thread "main" java.util.MissingFormatArgumentException: Format specifier '%s'
Ошибка 3: null вместо строки-шаблона
String s = String.format(null, "a");
Exception in thread "main" java.lang.NullPointerException
Ошибка 4: неверная ширина или флаг
String s = String.format("%0-5d", 1);
Exception in thread "main" java.util.IllegalFormatFlagsException: 0
Ошибка 5: применение числовых флагов к null
String s = String.format("%d", (Integer) null);
System.out.println(s);
Exception in thread "main" java.lang.NullPointerException
Замечание: стек трассировки в разных JVM частично отличается, но тип исключения и причина форматирования остаются предсказуемыми. Рекомендуется проверять соответствие типов и количество аргументов и учитывать возможные null-значения перед вызовом String.format.
Изменения и стабильность метода в версиях JDK
Метод String.format введён вместе с классом Formatter в JDK 5. С тех пор его поведение остаётся стабильным. Небольшие изменения могли коснуться поддержки локалей и обновления форматов даты/времени вслед за обновлениями стандартных библиотек и спецификаций Unicode. В практическом применении API не подвергался значительным изменениям в более поздних релизах Java. Для специфичных требований к локализации обычно используются NumberFormat и DateTimeFormatter, которые эволюционировали независимо от String.format.
Расширенные и редкие примеры использования
Несколько углублённых образцов применения с пояснениями.
1) Реализация собственного форматирования через интерфейс Formattable
public class Point implements java.util.Formattable {
private final int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
@Override
public void formatTo(java.util.Formatter formatter, int flags, int width, int precision) {
String out = String.format("(%d,%d)", x, y);
if (precision >= 0 && precision < out.length()) {
out = out.substring(0, precision);
}
if ((flags & java.util.FormattableFlags.LEFT_JUSTIFY) != 0) {
formatter.format("%-" + width + "s", out);
} else {
formatter.format("%" + width + "s", out);
}
}
}
Point p = new Point(10, 20);
String s = String.format("Point: %10s", p);
System.out.println(s);
Point: (10,20)
Комментарий: интерфейс позволяет задать собственную логику форматирования объектов при использовании %s.
2) Множественные спецификаторы даты, использование Instant и ZoneId
Instant now = Instant.parse("2026-04-24T08:30:00Z");
ZonedDateTime z = ZonedDateTime.ofInstant(now, ZoneId.of("Europe/Moscow"));
String s = String.format(Locale.US, "%1$tF %1$tT %1$tZ", z);
System.out.println(s);
2026-04-24 11:30:00 MSK
Комментарий: %t-спецификаторы принимают TemporalAccessor через обёртку; порядок и локаль влияют на отображение.
3) Форматирование BigDecimal с точной настройкой и группировкой
BigDecimal big = new BigDecimal("1234567.89123");
String s = String.format(Locale.US, "%,.3f", big);
System.out.println(s);
1,234,567.891
Комментарий: использование BigDecimal обеспечивает контроль точности вычислений, а формат задаёт вывод с группировкой.
4) Комбинация позиционных аргументов для локализованных сообщений
// Допустим нужно поменять порядок аргументов для других языков
String base = "{0} bought {1} items for {2}"; // MessageFormat удобнее
String s = String.format("%2$s: %1$d pcs, total %3$.2f", "Widget", 5, 123.456);
System.out.println(s);
// Повтор в разных местах
String s2 = String.format("%1$s %1$s %
Widget: 5 pcs, total 123.46 repeat repeat repeat
Комментарий: позиционные индексы и оператор < позволяют переиспользовать аргументы без повторной передачи.
5) Форматирование битовых масок и представление в разных системах счисления
int flags = 0b1011;
String s = String.format("dec=%d oct=%o hex=%#x", flags, flags, flags);
System.out.println(s);
dec=11 oct=13 hex=0xb
Комментарий: полезно при отладке низкоуровневых значений и при выводе двоичных/шестнадцатеричных представлений.
6) Использование Formatter для вывода в Appendable и в файл
try (Writer w = new FileWriter("out.txt");
Formatter fm = new Formatter(w, Locale.US)) {
fm.format("Name: %s, Score: %.1f%n", "Player", 99.5);
}
// Файл out.txt содержит одну строку
(файл) Name: Player, Score: 99.5
Комментарий: Formatter принимает Appendable, что делает возможным запись в потоки и обработку больших объёмов построчно.
7) Неочевидное поведение: %s и значение null
String s = String.format("Value: %s", (Object) null);
System.out.println(s);
Value: null
Комментарий: null печатается как строка "null", что отличается от исключения в случае примитивных форматов.