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 unString.System.out.printf(formato, args...): imprime directamente a consola.formato.formatted(args...): método de instancia enString, 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:
SLF4Jusa{}como placeholder en logs, sin llamar atoStringsi 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
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.