Відповідь "через те, що сканер має стан".
Дивлячись на коді для java.util.Scanner , ви побачите ряд приватних областей , таких як буфер і пов'язану з ним інформацією, Слічітель, шаблон, джерело вхідного сигналу, інформація про , якщо джерело закритий чи ні, типу останньої відповідності, інформація про те, чи остання річ була дійсною, чи ні, радікс, який використовується для чисел, локал (інформація про те, чи ви використовуєте .або ,як роздільник тисяч), і власний кеш LRU для нещодавно використаних шаблонів , інформація про останній виняток, що трапилася, деяка інформація про розбір чисел, деяка інформація про розбір булевих символів, зовсім трохи більше інформації про розбір цілих чисел ... і я думаю, що про це.
Як бачите, там досить великий блок тексту. Такий стан сканера. Для того, щоб сканер перейшов у статичний клас, цей стан потрібно було б зберігати десь в іншому місці. Спосіб C це робити насправді не має такого стану. У вас є fscanf. ФАЙЛ підтримує деякий стан щодо позиції, в якій він знаходиться (але це потрібно передавати для кожного виклику fscanf). Якщо сталася помилка, ви повинні обробити його (а потім ви починаєте писати код , який виглядає , як це ) - і це не говорить вам інформацію , як «Я очікував Integer, але знайшов String.»
Якщо дивитися на теоретично статичний сканер - весь стан підтримується поза класом, він не інкапсульований у межах класу. Інші біти коду можуть пов'язуватися з цими змінними. Коли інший код може погоджуватися зі станом класу, стає дуже важко міркувати про те, що буде робити клас у будь-якій ситуації.
Ви можете, можливо, написати щось на кшталт ScannerState { Locale loc; ... }і мати код, що призводить до:
ScannerState state = new ScannerState(a whole lot of arguments);
int foo = Scanner.nextInt(state);
Але тоді це набагато громіздкіше, ніж спочатку стан інкапсульований у межах об'єкта Сканера (і не потрібно переходити в стан).
Нарешті, Сканер реалізує інтерфейс, Iterator<String>який означає, що можна використовувати його в такому коді, як:
Scanner in = new Scanner(someFile);
whie(in.hasNext()) { ... }
Не маючи змоги отримати екземпляр класу Scanner, цей тип структури стає більш громіздким в межах об'єктно-орієнтованої мови.