Давайте начнем с перечисления проблем в вашем коде:
Ошибка компиляции в операторе return
вызвана тем, что fs
находится вне области действия, как описано в других ответах.
Когда вы делаете рекурсивный вызов getFileScanner()
, вы не присваиваете или не возвращаете результат. Так что он не вернется к звонящему.
Использование return
в блоке finally
является плохой идеей . Это раздавит (выбросит) любые другие исключения, которые могут распространяться в этой точке; например исключения, которые не соответствуют catch
или исключения, выданные в блоке catch
.
Вызов input.nextLine()
вызовет исключение, если базовый поток достиг EOF; например пользователь набрал [CONTROL] + D или что-то еще. Вам не нужно ловить его (он не проверен), но возвращение в блоке finally
подавляет его (вероятно), в результате чего вызывающий абонент получает null
вместо этого. Тьфу ...
Жесткая проводка System.in
и System.out
делает ваш метод менее пригодным для повторного использования. (Хорошо, это не может быть проблемой, которую вы должны решить в данном конкретном случае. И я не буду, ниже ...)
Теоретически, ваш метод может быть сделан, чтобы бросить StackOverflowError
; например если пользователь нажимает [ENTER] несколько раз. Эта проблема присуща вашему рекурсивному решению и является хорошей причиной не делать этого таким образом.
Наконец, вот версия метода, который решает эти проблемы:
public static Scanner getFileScanner() throws NoSuchElementException
{
Scanner input = new Scanner(System.in);
while (true) {
String file = input.nextLine();
try {
return new Scanner(new FileReader(file));
} catch (FileNotFoundException fe) {
System.out.println("Invalid filename. Try another:");
}
}
}
Обратите внимание, что я заменил рекурсию, избавился от finally
и объявил исключение, которое выдается. (Можно перехватить это исключение и либо сообщить о нем, либо повторно выбросить его как исключение для конкретного приложения.)