La entrada y salida reúne los mecanismos con los que un programa recibe datos y comunica resultados.
Hasta ahora, nuestros programas no recibían datos del exterior. Definíamos variables dentro del código, calculábamos algo y lo mostrábamos. Una aplicación interactiva necesita preguntar al usuario y responder.
Hoy vamos a ver el I/O (Input/Output) básico en consola.
Parece sencillo, pero Java tiene sus peculiaridades. Si vienes de C# (Console.ReadLine) o Python (input), verás que en Java leer del teclado requiere un pequeño “ritual” con la clase Scanner.
Salida de datos: System.out
Ya conocemos a nuestro viejo amigo System.out.println. Pero vamos a destriparlo un poco más, porque hay vida más allá del println.
System.out es un flujo de salida estándar (Standard Output Stream) que ya viene abierto y listo para usar.
Variantes de impresión
println()(Print Line): Imprime el texto y añade un salto de línea al final.print(): Imprime el texto y se queda esperando en la misma línea.printf()(Print Formatted): Si vienes de C, te resultará familiar. Permite formatear texto usando marcadores.
int edad = 25;
double altura = 1.75;
System.out.print("Hola, ");
System.out.println("usuario.");
// Salida: Hola, usuario. (con salto de línea al final)
// Usando concatenación clásica (un poco feo)
System.out.println("Tienes " + edad + " años y mides " + altura + "m.");
// Usando printf (más limpio y profesional)
System.out.printf("Tienes %d años y mides %.2fm.%n", edad, altura);En printf, %d es para enteros, %f para flotantes (podemos limitar decimales con %.2f), %s para textos y %n es el salto de línea multiplataforma.
Entrada de datos: la clase Scanner
Java no tiene una función global simple para leer (como cin en C++). En su lugar, usa la clase java.util.Scanner, que es un analizador de texto.
Scanner es muy potente: puede leer de la consola, de un archivo de texto o de una cadena, y es capaz de trocear la información (tokens) automáticamente.
Paso 1: importar e inicializar
Scanner no está en el paquete básico java.lang, así que hay que importarlo.
import java.util.Scanner; // 1. Importar
public class Main {
public static void main(String[] args) {
// 2. Crear una instancia conectada al teclado (System.in)
Scanner scanner = new Scanner(System.in);
// ... usar el scanner ...
// 3. Buena práctica: cerrar el scanner al terminar
scanner.close();
}
}Paso 2: leer datos
El Scanner tiene métodos específicos para cada tipo de dato primitivo.
System.out.print("Introduce tu edad: ");
int edad = scanner.nextInt(); // Lee un entero
System.out.print("Introduce tu peso: ");
double peso = scanner.nextDouble(); // Lee un double (ojo con usar coma o punto según tu idioma)
System.out.print("Introduce tu nombre: ");
String nombre = scanner.next(); // Lee UNA sola palabra (hasta el primer espacio)Atención con la configuración regional (Locale):
Si tu ordenador está en español, scanner.nextDouble() esperará una coma (2,5) como separador decimal. Si escribes un punto (2.5), lanzará una excepción InputMismatchException.
Puedes forzar el punto con scanner.useLocale(Locale.US);.
Leer líneas completas
Si quieres leer una frase entera (con espacios), scanner.next() no sirve porque se para al primer espacio. Debes usar scanner.nextLine().
El salto de línea pendiente en Scanner
Este es el error con el que todos nos hemos golpeado al aprender Java. Presta atención.
Si mezclas métodos de lectura de números (nextInt, nextDouble) con lectura de líneas (nextLine), ocurrirá algo extraño:
System.out.print("Dime un número: ");
int numero = scanner.nextInt();
System.out.print("Dime una frase: ");
String frase = scanner.nextLine(); // ¡El programa se salta esto!
System.out.println("Leído: " + numero + " y " + frase);¿Qué ha pasado?
- Escribes
42y pulsasEnter. - En el buffer de entrada hay:
42+\n(el salto de línea). nextInt()coge el42, pero deja el\nen el buffer.- Llamas a
nextLine(). Esta función lee hasta encontrar un salto de línea. Como lo primero que encuentra es el\nque sobró antes, piensa: “¡Ah, una línea vacía!”, la consume y termina.
La Solución: Siempre que leas un número y luego vayas a leer un texto, debes hacer una lectura extra para “limpiar” el buffer.
int numero = scanner.nextInt();
scanner.nextLine(); // <--- CONSUMIMOS EL ENTER SOBRANTE (Limpieza)
System.out.print("Dime una frase: ");
String frase = scanner.nextLine(); // Ahora sí funcionaLa alternativa: la clase Console
Java 6 introdujo System.console(). Es una forma más directa de leer, especialmente diseñada para contraseñas porque no muestra lo que escribes.
Console consola = System.console();
if (consola != null) {
String usuario = consola.readLine("Usuario: ");
char[] pass = consola.readPassword("Contraseña: ");
}El problema de Console
Seguramente si pruebas el código anterior en IntelliJ o Eclipse, te dará error (NullPointerException).
Esto es porque System.console() solo funciona si ejecutas el programa desde una terminal real (CMD, Bash). Los IDEs suelen envolver la consola y System.console() devuelve null.