La respuesta es "porque un escáner tiene estado".
Al mirar el código de java.util.Scanner , verá una serie de campos privados como un búfer y su información asociada, un Matcher, un Patrón, una fuente de entrada, información sobre si la fuente está cerrada o no, el tipo de lo último que coincidió, información sobre si lo último fue una coincidencia válida o no, la raíz utilizada para los números, la configuración regional (información sobre si está utilizando .
o ,
como un separador de miles) y su propio caché LRU para patrones utilizados recientemente , la información sobre la última excepción que se encontró, alguna información sobre el análisis de números, alguna información sobre el análisis de booleanos, bastante más información sobre el análisis de enteros ... y creo que eso es todo.
Como puede ver, ese es un bloque de texto bastante grande allí. Ese es el estado del escáner. Para convertir el escáner en una clase estática, ese estado debería almacenarse en otro lugar. La forma C de hacerlo realmente no tiene tanto estado. Tienes un fscanf
. El ARCHIVO mantiene algún estado acerca de la posición en la que se encuentra (pero eso debe pasarse para cada invocación de fscanf
). Si hubo un error, hay que procesarlo (y después de empezar a escribir código que se parece a esto ) - y que no le dicen la información como "Me esperaba un entero, pero encontró una cadena".
Cuando uno mira el escáner teóricamente estático: todo el estado se mantiene fuera de la clase, no está encapsulado dentro de la clase. Otros bits de código podrían jugar con esas variables. Cuando otro código puede jugar con el estado de la clase, se hace muy difícil razonar sobre lo que la clase hará en una situación dada.
Podría, tal vez, escribir algo así ScannerState { Locale loc; ... }
y tener un código que resulte en:
ScannerState state = new ScannerState(a whole lot of arguments);
int foo = Scanner.nextInt(state);
Pero entonces, esto es mucho más engorroso que tener el estado encapsulado dentro de un objeto Scanner en primer lugar (y sin necesidad de pasar en el estado).
Por último, el escáner implementa la interfaz, lo Iterator<String>
que significa que se puede usar en código como:
Scanner in = new Scanner(someFile);
whie(in.hasNext()) { ... }
Sin poder obtener una instancia de la clase Scanner, este tipo de estructura se vuelve más engorroso dentro de un lenguaje orientado a objetos.
FILE*
(estado de posición) en C.Iterator
- noIterable
. Es imposible usar el escáner en bucle mejorado.respuesta corta: no lo haces. Puede obtener la entrada del usuario sin usar una instancia de escáner.
Por ejemplo: https://docs.oracle.com/javase/tutorial/essential/io/cl.html o
http://alvinalexander.com/blog/post/java/java-source-code-read-command-line -entrada
fuente
String orgName = (new BufferedReader(new InputStreamReader(System.in))).readLine();
Eso es horriblemente complicado en comparación con el uso de aScanner
y también crea nuevas instancias de no uno sino dos objetos solo para descartarlos de inmediato.