2014-10-29 8 views
2

Если у меня есть метод, который бросает FilenotFoundException, потому что я использую объект Scanner для чтения файла, если ошибка действительно возникает, закрывается ли объект сканера или мне все еще нужно это делать, когда я обрабатываю исключение?- это java-сканер, закрытый, когда выбрано исключение?

Я знаю, что когда я использую блок try-catch-finally в моем методе для обработки исключения, я закрываю объект сканера, но если мне нужно сделать это внутри метода в другом объекте, который ловит исключение, У меня не будет доступа к объекту сканера.

Пожалуйста, держите пояснения просто ... очевидно, что я новичок в java (и OO в целом).

ответ

3

Если вы используете код, как этот Scanner scanner = new Scanner(new File("C:/abc.txt")); Если бросает исключение, scanner объект это сам не будет создана, поэтому нет необходимости закрывать его.

Но лучший способ кодирования, как показано ниже. вы можете закрыть в конце блока.

Scanner scanner=null; 
try 
{ 
    scanner = new Scanner(new File(path)); 
    //your code here 
} 
catch(FileNotFoundException e)//either catch or throw out 
{ 
    //log it 
} 
finally 
{ 
    if(null !=scanner) 
    { 
     scanner.close(); 
    } 
} 
2

Основание FileInputStream даже не открывается, если файл не найден, когда вы делаете new Scanner(File).

Практически следует закрыть сканер в , наконец, блок. Если сканер уже закрыт, то закрытый вызов не будет иметь никакого эффекта.

Или вы можете попробовать конструкцию try-with-resources, которая автоматически закроет ресурсы, если произойдет какое-то исключение.

+1

'try-with-resources', кажется, лучший подход, так как он требует меньше кода – superbob

+1

@superbob это лучший подход по нескольким причинам, чем просто« меньше кода »:). – Tom

0

Я думаю, вы должны закрыть объект сканера в , наконец, блок, независимо от того, вы поймаете исключение или нет.

1

Предположим, вы делаете это:

Scanner scanner = new Scanner(new File("/file/does/not/exist")); 

и конструктор бросает FileNotFoundException. Прежде всего следует отметить, что конструктор не возвращает объект Scanner. Вместо этого выражение new закончится ненормально, а присваивание scanner не произойдет. В конечном итоге управление будет обработано каким-либо обработчиком для исключения, которое не сможет ссылаться на scanner, поскольку оно выходит за рамки.

Так, чтобы ответить на ваш вопрос:

если ошибка действительно брошено, делает объект сканер получить закрытым, или же я до сих пор сделать это, когда я обрабатывать исключение?

Если FileNotFoundException брошено конструктором, нет Scanner объекта close() ... так что вам не нужно, чтобы закрыть его.

Однако, в зависимости от того, как вы написали код, вы можете связаться с обработчиком или блоком finally, не зная, было ли вообще исключено исключение, независимо от того, было ли оно создано в конструкторе или после завершения конструктора. Способ справиться с этим зависит от того, какую версию Java вы используете. До Java 7, идиома - это что-то вроде ответа Шангета.Для Java 7, а затем вы можете написать это:

try (Scanner scanner = new Scanner(new File(path))) { 
    //your code here 
} catch (FileNotFoundException e) { 
    //log it 
} 

Обратите внимание, что синтаксис «примерочных с-ресурсов» имеет неявный finally, что автоматически вызывает close() на каждом из (autocloseable) ресурсов, объявленных на старте try. Это освобождает вас от ответственности за ошибочный код, который закрывает ресурсы в различных возможных случаях успеха и сбоя.


Фактически, мы можем воспринимать этот уровень глубже. Конструктор Scanner вызывает FileInputStream, чтобы открыть файл, и в этом случае будет выведено исключение FileNotFoundException. В свою очередь, это вызовет метод native open, чтобы фактически открыть файл. Если что-то пошло не так в этом процессе (и возникает исключение), то ответственность за конструкторы заключается в том, чтобы гарантировать освобождение любых ресурсов (например, собственные потоки), прежде чем разрешить распространение исключения.

Должен работать так, потому что неудавшиеся конструкторы ничего не возвращают, и они не могут полагаться на что-то еще в стеке, зная, как выпустить ресурсы в конкретном обработчике исключений.

+0

+1 .. Отличный ответ :) – TheLostMind

Смежные вопросы