Java - объявление сканера - PullRequest
       9

Java - объявление сканера

0 голосов
/ 05 сентября 2018

Я очень новичок в Java. Вот очень простой метод переключения.

Когда пользователь вводит здесь String, он выдаст ошибку, и catch снова вызовет этот метод как закодированный.

и вот мой вопрос о сканере.

Я понял, что мне нужно поставить эти

Scanner sc = new Scanner(System.in);

в теле "try", если бы я хотел, чтобы он снова велел мне печатать физически, но почему? Зачем печатать

int select = sc.nextInt();

не достаточно?

Будет

int select1 = sc.nextInt(); и

int select2 = sc.nextInt(); будет таким же, потому что у него такой же экземпляр "sc"?

 public void reAsk(){
  System.out.println("Type a number")
  Scanner sc = new Scanner(System.in);

  try {
        int select = sc.nextInt();
        switch (select) {

        case 1:
            System.out.println("1");
            break;
        case 2:
            System.out.println("2");
            break;
        case 3:
            System.out.println("3");
            break;


    } catch (InputMismatchException e) {
        System.out.println("Please type int");
        reAsk();
    }
}

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Вызов nextInt() (или любой метод next()) просто попытается прочитать следующий токен (в приведении nextInt(), возможный знак (+/-) и цифры) в потоке, например: стандартный ввод.

Если вы введете: 0 1 2, то при каждом последующем вызове nextInt() будут возвращаться 0, 1 и 2.

Чтобы продолжить с Scanner, вам не нужно создавать Scanner каждый раз, когда вызывается метод reAsk, и вам не нужно использовать рекурсию в таком тривиальном случае (если только это не упражнение ): вы можете использовать его повторно, но вы должны быть осторожны с символами, оставленными в буфере в случае ошибок.

Например:

Scanner sc = new Scanner(System.in);
try {    
  ...
  int select;
  for (;;) {
    try {
      select = sc.nextInt();
      break;
    } catch (InputMismatchException ignored) {
      continue;
    }
  }
  // select is always initialized in that case
  switch (select) {
    ...
  }
}

Это сделает бесконечный цикл, потому что sc не может прочитать int и в буфере все еще есть недопустимый символ int (например: 'a 1').

Вы можете использовать sc.next() для продвижения (это отбросит следующий токен, например: a в приведенном выше примере).

Но было бы разумнее использовать sc.hasNextInt() в этом случае:

Scanner sc = new Scanner(System.in);
while (!sc.hasNextInt() && sc.hasNext()) {
  sc.next(); // advance / discard the invalid token
}

// we don't care about result of hasNext() here.
int select = sc.nextInt();

Как сказано в комментарии выше, мы не тестируем hasNext() по двум основным причинам:

  • если hasNext() возвращает false, то более вероятно, что поток закончился. Возможно, вы захотите вызвать hasNextInt() до nextInt(), и если он вернет false, правильно завершите ваш метод. В этом примере произойдет сбой с NoSuchElementException.
  • System.in вероятно закончится, только если он будет перенаправлен (например: java Main < foobar.txt, echo a | java Main) или если будет вызвана какая-то последовательность (я не помню, но я верю, что это Ctrl + Z) или если вы закрыли (в) непосредственно в Java (System.in.close()).

Примечание: в большинстве случаев такие ресурсы, как Scanner, создаются в try-with-resources , например:

try (Scanner sc = new Scanner(System.in)) {
  ...
}

Хотя это хорошая практика, это закроет System.in, и вы никогда не сможете его использовать:

try (Scanner sc = new Scanner(System.in)) {
  String next = sc.next(); // again, without hasNext().
}
try (Scanner sc = new Scanner(System.in)) {
  String next = sc.next(); // fail NoSuchElementException (stream is closed).
}

В вашем случае вы можете игнорировать try-with-resources .

0 голосов
/ 05 сентября 2018

Ваши выводы неверны. Я исправил ваш код, надеюсь, это ответит на ваш вопрос:

import java.util.InputMismatchException;
import java.util.Scanner;

public class Main {

    public static void reAsk() {
    System.out.println("Type a number");
    Scanner sc = new Scanner(System.in);

    try {
        int select = sc.nextInt();
        switch (select) {

        case 1:
            System.out.println("1");
            break;
        case 2:
            System.out.println("2");
            break;
        case 3:
            System.out.println("3");
            break;

        }
    } catch (InputMismatchException e) {
        reAsk();
    }
    }

    public static void main(String[] args) {
        reAsk();
    }

}

Нет необходимости инициализировать класс сканера внутри try catch. У вас просто было несколько синтаксических ошибок. Во-первых, в Java каждый оператор должен заканчиваться точкой с запятой, вы не добавили точку с запятой после System.out.println("Type a number").

...