A resposta é "porque um scanner possui estado".
Observando o código do java.util.Scanner , você verá vários campos particulares, como um buffer e suas informações associadas, um Matcher, um Pattern, uma fonte de entrada, informações sobre se a fonte está fechada ou não, o tipo da última coisa correspondida, informações sobre se a última coisa foi uma correspondência válida ou não, a raiz usada para números, o local (informações sobre se você está usando .
ou ,
como separador de milhares) e seu próprio cache LRU para padrões usados recentemente , as informações sobre a última exceção encontrada, algumas informações sobre a análise de números, algumas informações sobre a análise de booleanos, bastante mais informações sobre a análise de números inteiros ... e acho que é isso.
Como você pode ver, é um bloco de texto bastante grande lá. Esse é o estado do scanner. Para transformar o Scanner em uma classe estática, esse estado precisaria ser armazenado em outro lugar. A maneira C de fazê-lo realmente não tem tanto estado com isso. Você tem um fscanf
. O FILE mantém algum estado sobre a posição em que está (mas isso precisa ser passado para cada chamada de fscanf
). Se houve um erro, é necessário processá-lo (e então você começa a escrever um código parecido com este ) - e isso não informa informações como "Eu estava esperando um número inteiro, mas encontrei uma string".
Quando se olha o scanner teoricamente estático - todo o estado é mantido fora da classe, não é encapsulado dentro da classe. Outros bits de código podem mexer com essas variáveis. Quando outro código pode mexer com o estado da classe, fica muito difícil argumentar sobre o que a classe fará em qualquer situação.
Talvez você possa escrever algo como ScannerState { Locale loc; ... }
e ter um código que resulte em:
ScannerState state = new ScannerState(a whole lot of arguments);
int foo = Scanner.nextInt(state);
Porém, isso é muito mais complicado do que ter o estado encapsulado em um objeto Scanner em primeiro lugar (e não precisar passar no estado).
Por fim, o Scanner implementa a interface, o Iterator<String>
que significa que é possível usá-lo em códigos como:
Scanner in = new Scanner(someFile);
whie(in.hasNext()) { ... }
Sem conseguir obter uma instância da classe Scanner, esse tipo de estrutura se torna mais complicado dentro de uma linguagem orientada a objetos.
FILE*
(estado posição) em C.Iterator
- nãoIterable
. É impossível usar o Scanner no loop for avançado.resposta curta: você não. Você pode obter a entrada do usuário sem usar uma instância do Scanner.
Por exemplo: https://docs.oracle.com/javase/tutorial/essential/io/cl.html ou
http://alvinalexander.com/blog/post/java/java-source-code-read-command-line -entrada
fonte
String orgName = (new BufferedReader(new InputStreamReader(System.in))).readLine();
Isso é terrivelmente complicado em comparação ao uso deScanner
ae também cria novas instâncias de não um, mas dois objetos apenas para descartá-los imediatamente.