Formateo de texto: String.format, printf y formatted

Básico
Java
Java
Actualizado: 18/04/2026

Tres formas de formatear texto

Java ofrece tres APIs equivalentes para producir cadenas con placeholders al estilo printf de C:

  • String.format(formato, args...): método estático que devuelve un String.
  • System.out.printf(formato, args...): imprime directamente a consola.
  • formato.formatted(args...): método de instancia en String, desde Java 15.

Los tres comparten la misma sintaxis de especificadores.

// String.format
String s = String.format("Hola, %s. Tienes %d años.", "Ana", 30);

// printf (imprime, no devuelve)
System.out.printf("Hola, %s. Tienes %d años.%n", "Ana", 30);

// formatted (moderno y fluido)
String s2 = "Hola, %s. Tienes %d años.".formatted("Ana", 30);

formatted es especialmente elegante con text blocks:

String reporte = """
Informe del %s:
============================
Ventas: %,d €
Clientes: %,d
Promedio: %.2f €
""".formatted(fecha, ventas, clientes, promedio);

Especificadores principales

Un especificador empieza con %, opciones intermedias, y termina con un carácter de conversión:

%[flags][width][.precision]conversion

Conversiones comunes

| Conversión | Tipo | Ejemplo | |------------|------|---------| | %s | Cualquier objeto (usa toString()) | String.format("%s", "hola") a "hola" | | %d | Entero (int, long, byte, short) | String.format("%d", 42) a "42" | | %f | Decimal (float, double) | String.format("%f", 3.14) a "3.140000" | | %e | Decimal notación exponencial | String.format("%e", 1234.5) a "1.234500e+03" | | %x / %X | Hexadecimal (min/mayús) | String.format("%x", 255) a "ff" | | %o | Octal | String.format("%o", 8) a "10" | | %b | Boolean | String.format("%b", null) a "false" | | %c | Carácter | String.format("%c", 'A') a "A" | | %% | Literal % | String.format("100%%") a "100%" | | %n | Salto de línea de la plataforma | \n en Unix, \r\n en Windows |

Flags

| Flag | Significado | Ejemplo | |------|-------------|---------| | - | Alinear a la izquierda | "%-10s|".formatted("ab") a "ab |" | | + | Forzar signo en números | "%+d".formatted(5) a "+5" | | | Espacio antes de positivos | "% d".formatted(5) a " 5" | | 0 | Relleno con ceros | "%05d".formatted(42) a "00042" | | , | Separador de miles (según Locale) | "%,d".formatted(1000000) a "1,000,000" | | ( | Números negativos entre paréntesis | "%(d".formatted(-5) a "(5)" | | # | Formato alternativo (octal con 0, hex con 0x) | "%#x".formatted(255) a "0xff" |

Ancho y precisión

  • Ancho: mínimo de caracteres: "%10d".formatted(5) a " 5" (9 espacios + 5).
  • Precisión: para decimales, número de cifras tras el punto; para strings, máximo de caracteres.
String.format("%.2f", 3.14159); // "3.14"
String.format("%10.2f", 3.14); // " 3.14"
String.format("%-10.3s", "abcdef"); // "abc " (max 3 chars, alinear izq)

Combinaciones comunes:

String.format("%08.2f", 3.14); // "00003.14"
String.format("%+,10d", 1234567); // "+1,234,567"

Tabla bien formateada

Un ejemplo clásico: tabla con columnas alineadas.

List<Empleado> empleados = ...;

System.out.printf("%-20s %5s %10s%n", "Nombre", "Edad", "Salario");
System.out.println("-".repeat(40));
for (var e : empleados) {
    System.out.printf("%-20s %5d %10.2f%n",
        e.nombre(), e.edad(), e.salario());
}

Salida:

Nombre Edad Salario
----------------------------------------
Ana 30 2500.00
Roberto 45 3500.75
Carmen 28 2800.50

Formatear fechas

La conversión %t es especial: toma un argumento de fecha (Date, Calendar, long, Temporal) y un segundo carácter que indica qué parte formatear.

LocalDateTime ahora = LocalDateTime.now();

System.out.printf("Día: %tY-%tm-%td%n", ahora, ahora, ahora);
// Día: 2026-04-17

System.out.printf("Hora: %tH:%tM:%tS%n", ahora, ahora, ahora);
// Hora: 15:23:45

Se puede usar el mismo argumento varias veces con %<:

System.out.printf("%tY-%<tm-%<td %<tH:%<tM:%<tS%n", ahora);
// 2026-04-17 15:23:45

En la práctica, para fechas es preferible DateTimeFormatter en vez de %t:

System.out.println(ahora.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));

Argumentos posicionales

Puedes referenciar argumentos por índice con %<n>$:

String.format("%1$s es %2$d años mayor que %3$s. %2$d es mayor que %4$d.",
    "Ana", 5, "Bob", 3);
// "Ana es 5 años mayor que Bob. 5 es mayor que 3."

Útil para traducciones (el orden de las palabras cambia entre idiomas pero los índices referencian los mismos argumentos).

Locale

Los separadores de miles y decimal dependen del locale. Por defecto, String.format usa el locale por defecto de la JVM:

String.format("%.2f", 3.14); // "3,14" en España, "3.14" en US

Puedes forzar un locale:

String.format(Locale.US, "%.2f", 3.14); // "3.14"
String.format(Locale.GERMANY, "%,d", 1000); // "1.000"

Para textos que van a usuarios, considera el locale; para datos técnicos (logs, JSON), usa Locale.ROOT o Locale.US para evitar ambigüedades.

Cuándo usar cada uno

| Situación | Usa | |-----------|-----| | Construir un String y guardarlo | String.format o "...".formatted(...) | | Imprimir directo a consola | System.out.printf | | En tests o logs | Evita si es muy frecuente (caro): prefiere String.format o loggers (%s placeholders) | | Concatenación simple sin formato | "a " + b + " c" (el compilador lo optimiza) | | Plantillas largas con text block | """...""".formatted(...) |

Alternativas modernas

  • MessageFormat (java.text): más formal, útil para plurales y localización avanzada.
  • Template strings / String templates (preview en Java 21-23): sintaxis STR."Hola \{nombre}". En fase de diseño; en 2026 puede estabilizarse.
  • Librerías: SLF4J usa {} como placeholder en logs, sin llamar a toString si el log no se emite.

Ejemplos recopilados

// Factura formateada
String factura = """
--- FACTURA %d ---
Cliente: %s
Fecha: %tF

Subtotal: %,10.2f €
IVA 21%%: %,10.2f €
-------------------
TOTAL: %,10.2f €
""".formatted(id, cliente, fecha, subtotal, iva, total);

// Porcentaje de progreso
System.out.printf("\rProcesando: %6.2f%%", porcentaje);

// Tabla alineada
System.out.printf("| %-30s | %8d | %10.2f |%n", nombre, cantidad, precio);

// Formato con locale US para CSV
String csv = String.format(Locale.US, "%s,%d,%.2f", nombre, edad, salario);

Resumen

String.format, printf y formatted son las herramientas estándar para formatear texto en Java. Dominar sus especificadores permite generar reportes limpios, formatear logs alineados y construir plantillas legibles. En 2026, formatted con text blocks es la combinación idiomática para cualquier formateo no trivial.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Java es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Java

Explora más contenido relacionado con Java y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Usar String.format para construir strings con placeholders. Aplicar System.out.printf para imprimir texto formateado. Usar .formatted() como alternativa fluida (Java 15+). Dominar especificadores comunes: %s, %d, %f, %x, %n, %t. Controlar ancho, precisión, alineación y relleno. Localizar formato según Locale.