Hasta ahora, nuestros programas han sido un poco «sordos». Pueden ejecutar cierta lógica y mostrar resultados, pero no pueden reaccionar a la información que el usuario introduce en tiempo real. Hoy vamos a ver cómo hacerlo de forma sencilla.
En Java, una de las herramientas más comunes para leer datos introducidos por teclado es Scanner. Aunque es una herramienta muy potente (y que exploraremos más a fondo cuando hablemos de Clases y Objetos), hoy nos centraremos en su uso básico y en cómo evitar un problema muy común que confunde a casi todos al empezar.
1. Preparando el terreno: cómo «conectar» el Scanner 🔌
Para poder usar esta herramienta, necesitamos hacer dos cosas primero.
1.1. Importar la herramienta
Java tiene sus herramientas organizadas en «cajas». Scanner no está en la caja principal, así que debemos decirle a nuestro programa de dónde cogerla. Esto se hace con una sentencia import al principio de nuestro archivo .java (antes de public class…).
import java.util.Scanner; // Le decimos a Java dónde encontrar la herramienta Scanner
public class MiPrograma {
    public static void main(String[] args) {
        // ... nuestro código irá aquí ...
    }
}
Si has configurado bien tu IDE, normalmente este import se añadirá automáticamente cuando termines el paso que va a continuación.
1.2. Inicializar el Scanner
Una vez importada, necesitamos «encenderla» y conectarla al teclado. Para ello, usamos una instrucción especial dentro de nuestro main. Por ahora, trataremos esta línea como una «fórmula de inicialización» necesaria y no entraremos en qué implica ni cómo funciona:
public static void main(String[] args) {
    // Fórmula para conectar nuestro 'scanner' al teclado (System.in)
    Scanner scanner = new Scanner(System.in);
    
    // A partir de aquí, ya podemos usar la variable 'scanner' para leer
}
2. Leyendo datos: nextInt(), nextDouble() y next() 🔢
La herramienta scanner tiene varios métodos para leer tipos de datos específicos. Los más usados son:
scanner.nextInt(): Lee el próximo número entero que encuentre.scanner.nextDouble(): Lee el próximo número decimal que encuentre.scanner.next():scanner.next(): Lee el próximo token del teclado. Un token es una secuencia de caracteres que se lee hasta que elScannerencuentra un delimitador. Por defecto, los delimitadores son todos los espacios en blanco (espacios, tabuladores, saltos de línea).- Ejemplo: Si el usuario escribe 
Hola mundoy pulsa Enter,next()leerá y devolverá solo"Hola". La cadena"mundo"se quedará en el búfer esperando la próxima llamada de lectura. 
- Ejemplo: Si el usuario escribe 
 
Hay muchos más métodos que empiezan por next, hazte a la idea de que uno por tipo primitivo excepto para char, no hay un nextChar.
Veamos un ejemplo:
Scanner scanner = new Scanner(System.in);
System.out.print("Introduce tu edad: ");
int edad = scanner.nextInt();
System.out.print("Introduce tu nota media: ");
double nota = scanner.nextDouble();
System.out.print("Introduce tu nombre (solo nombre): ");
String nombre = scanner.next();
System.out.println("Hola, " + nombre + ". Tienes " + edad + " años y una nota de " + nota);
¿Qué pasa si el usuario introduce un dato incorrecto? 💥
¡Ojo! Mucho cuidado porque si el usuario, al indicar la edad dice «doce» en vez de 12, nuestro programa explotará. Los métodos como nextInt(), nextDouble(), etc. son muy estrictos. nextInt(), por ejemplo, espera (o «parsea») una secuencia de caracteres que formen un número entero.
¿Pero qué ocurre si el programa pide una edad (nextInt()) y el usuario escribe "doce" en lugar de 12?
El Scanner intentará convertir la palabra "doce" en un número, y al no poder hacerlo, lanzará una excepción (concretamente, una InputMismatchException).
Como aún no hemos visto cómo gestionar excepciones en Java (con try-catch), este evento detendrá nuestro programa bruscamente con un error en la consola. Es un comportamiento «frágil» que aprenderemos a robustecer más adelante, cuando hablemos de la gestión de excepciones en Java.
Por ahora quédate con que debes introducir los datos bien hasta que sepamos tomar medidas que eviten situaciones no deseadas.
3. El gran desafío: el búfer de entrada y nextLine() 🚧
Todo funciona bien hasta que queremos leer una línea de texto completa (por ejemplo, un nombre y apellidos). Para eso, existe el método scanner.nextLine().
Pero, ¿qué pasa si mezclamos nextInt() con nextLine()? Probemos.
Código INCORRECTO:
Scanner scanner = new Scanner(System.in);
System.out.print("Introduce tu edad: ");
int edad = scanner.nextInt(); // El usuario escribe '25' y pulsa ENTER
System.out.print("Introduce tu nombre completo: ");
String nombreCompleto = scanner.nextLine(); // ¡El programa no se detiene a esperar!
System.out.println("Hola, " + nombreCompleto + ", tienes " + edad + " años.");
Salida del programa:
Introduce tu edad: 25
Introduce tu nombre completo: 
Hola, , tienes 25 años.
¡El programa ha saltado la petición del nombre! ¿Por qué?
La explicación: la «cola de espera» (búfer)
Imagina que entre tu teclado y Java hay una «cola de espera» o búfer.
- Cuando el programa pide la edad, tú escribes 
25y pulsas la tecla Enter. - En ese momento, en el búfer se colocan los caracteres: 
2,5y el carácter de nueva línea\n(que representa la tecla Enter). - El método 
nextInt()llega al búfer. Es un lector «selectivo»: solo le interesan los números. Coge el2y el5, los convierte en el entero25y se va. - Problema: El carácter 
\nse ha quedado solo en el búfer. - Llamamos a 
scanner.nextLine(). Este método es un lector «exhaustivo»: su trabajo es leer todo lo que haya en el búfer hasta que se encuentre un\n. nextLine()mira el búfer, ve el\ninmediatamente, lo coge (lo «consume») y dice: «¡Trabajo hecho! El usuario ha introducido una línea vacía».- Por eso, 
nombreCompletose queda con una cadena vacía ("") y el programa nunca te dio la oportunidad de escribir. 
4. La solución: limpiar el búfer 🧹
La solución es sencilla una vez que se entiende el problema. Después de usar un lector «selectivo» como nextInt() o nextDouble(), y antes de usar un nextLine(), debemos consumir ese \n que ha sobrado.
Lo hacemos realizando una «lectura fantasma»:
Código CORRECTO:
Scanner scanner = new Scanner(System.in);
System.out.print("Introduce tu edad: ");
int edad = scanner.nextInt(); // El búfer queda con: \n
// --- LA SOLUCIÓN MÁGICA ---
// Consumimos el '\n' que sobraba en el búfer
scanner.nextLine(); 
System.out.print("Introduce tu nombre completo: ");
String nombreCompleto = scanner.nextLine(); // Ahora sí, el búfer está vacío y espera tu entrada
System.out.println("Hola, " + nombreCompleto + ", tienes " + edad + " años.");
Regla de oro: Después de un
nextInt(),nextDouble(),next()o cualquier otronextLoQueSea()que no seanextLine(), si la siguiente lectura que vas a hacer es unnextLine(), inserta siempre unscanner.nextLine();extra en medio para limpiar el búfer.
5. Una última buena práctica: cerrar el Scanner 🚪
El Scanner es una herramienta que «abre una conexión» con el teclado. Al igual que cerramos un archivo después de usarlo, es una buena práctica cerrar el escáner cuando ya no vayamos a leer más datos, liberando así los recursos.
Esto se hace (normalmente al final de nuestro main) con:
Java
scanner.close();
Conclusión
Scanner es nuestra puerta de entrada a la interactividad. Es fácil de usar para leer números y palabras sueltas. Su único «truco» es recordar el comportamiento del búfer de entrada cuando mezclamos lecturas selectivas (nextInt) con lecturas de línea completa (nextLine).
¡Con el «truco» de la limpieza de búfer, ya estás listo para crear programas que dialoguen con el usuario!


Deja una respuesta