La risposta è "perché uno scanner ha stato."
Esaminando il codice per java.util.Scanner , vedrai un certo numero di campi privati come un buffer e le sue informazioni associate, un Matcher, un Pattern, una fonte di input, informazioni su se la fonte è chiusa o meno, il tipo di l'ultima cosa abbinata, le informazioni su se l'ultima cosa era una corrispondenza valida o meno, la radice utilizzata per i numeri, le impostazioni locali (informazioni su se si utilizza .
o ,
come separatore di migliaia) e la propria LRU cache per i pattern usati di recente, le informazioni sull'ultima eccezione che si è incontrata, alcune informazioni sull'analisi dei numeri, alcune informazioni sull'analisi dei booleani, un po 'più di informazioni sull'analisi degli interi ... e penso a questo proposito.
Come puoi vedere, questo è un blocco di testo abbastanza grande lì. Questo è lo stato dello Scanner. Al fine di rendere lo Scanner in una classe statica, tale stato dovrebbe essere archiviato da qualche altra parte. Il modo C di farlo in realtà non ha molto significato. Hai un fscanf
. Il FILE mantiene uno stato sulla posizione in cui si trova (ma che deve essere passato per ogni chiamata di fscanf
). Se c'è stato un errore, devi elaborarlo (e poi inizi a scrivere codice simile a questo ) - e questo non lo fa ti dico informazioni come "Mi aspettavo un intero, ma ho trovato una stringa."
Quando si esamina lo Scanner teoricamente statico - tutto lo stato viene mantenuto al di fuori della classe, non è incapsulato all'interno della classe. Altri bit di codice potrebbero armeggiare con quelle variabili. Quando un altro codice può armeggiare con lo stato della classe, diventa molto difficile ragionare su ciò che la classe farà in una data situazione.
Potresti, forse, scrivere qualcosa come ScannerState { Locale loc; ... }
e avere il codice che risulta in:
ScannerState state = new ScannerState(a whole lot of arguments);
int foo = Scanner.nextInt(state);
Tuttavia, questo è molto più ingombrante che avere lo stato incapsulato all'interno di un oggetto Scanner in primo luogo (e non dover passare nello stato).
Infine, lo Scanner implementa l'interfaccia di Iterator<String>
, il che significa che è possibile utilizzarlo in codice come:
Scanner in = new Scanner(someFile);
whie(in.hasNext()) { ... }
Senza poter ottenere un'istanza della classe Scanner, questo tipo di struttura diventa più ingombrante all'interno di un linguaggio orientato agli oggetti.