Die Antwort lautet "weil ein Scanner einen Status hat".
Wenn Sie sich den Code für java.util.Scanner ansehen, sehen Sie eine Reihe privater Felder wie einen Puffer und die zugehörigen Informationen, einen Matcher, ein Muster, eine Eingabequelle sowie Informationen darüber, ob die Quelle geschlossen ist oder nicht, den Typ Informationen darüber, ob das Letzte übereinstimmte, Informationen darüber, ob das Letzte eine gültige Übereinstimmung war oder nicht, der für Zahlen verwendete Radix, das Gebietsschema (Informationen darüber, ob Sie .
oder ,
als Tausendertrennzeichen verwenden) und ein eigener LRU-Cache für kürzlich verwendete Muster , die Informationen über die letzte Ausnahme, die aufgetreten ist, einige Informationen über das Parsen von Zahlen, einige Informationen über das Parsen von Booleschen Werten, einiges mehr Informationen über das Parsen von ganzen Zahlen ... und ich denke, das ist es auch.
Wie Sie sehen können, ist das dort ein ziemlich großer Textblock. Das ist der Zustand des Scanners. Um den Scanner zu einer statischen Klasse zu machen, müsste dieser Status an einer anderen Stelle gespeichert werden. Die C-Methode hat wirklich nicht so viel zu bieten. Du hast eine fscanf
. Die DATEI behält einen Status über die Position bei, an der sie sich befindet (dies muss jedoch bei jedem Aufruf von übergeben werden fscanf
). Wenn es einen Fehler, haben Sie es zu verarbeiten (und dann das Schreiben beginnen Sie Code, der aussieht wie diese ) - und das Ihnen nicht sagen , Informationen wie „Ich erwarte eine Integer, fanden aber einen String.“
Wenn man sich den theoretisch statischen Scanner ansieht - der gesamte Status wird außerhalb der Klasse beibehalten, ist er nicht in der Klasse gekapselt. Andere Codebits könnten an diesen Variablen basteln. Wenn anderer Code am Status der Klasse basteln kann, ist es sehr schwierig zu überlegen, was die Klasse in einer bestimmten Situation tun wird.
Sie könnten vielleicht so etwas schreiben ScannerState { Locale loc; ... }
und Code haben, der Folgendes ergibt:
ScannerState state = new ScannerState(a whole lot of arguments);
int foo = Scanner.nextInt(state);
Dies ist jedoch viel umständlicher, als wenn der Status überhaupt in einem Scannerobjekt eingekapselt ist (und der Status nicht übergeben werden muss).
Schließlich implementiert der Scanner die Schnittstelle, Iterator<String>
was bedeutet, dass man sie in Code verwenden kann, wie zum Beispiel:
Scanner in = new Scanner(someFile);
whie(in.hasNext()) { ... }
Ohne eine Instanz der Scannerklasse abrufen zu können, wird diese Art von Struktur in einer objektorientierten Sprache umständlicher.