Предположим, вы делаете это:
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
, чтобы фактически открыть файл. Если что-то пошло не так в этом процессе (и возникает исключение), то ответственность за конструкторы заключается в том, чтобы гарантировать освобождение любых ресурсов (например, собственные потоки), прежде чем разрешить распространение исключения.
Должен работать так, потому что неудавшиеся конструкторы ничего не возвращают, и они не могут полагаться на что-то еще в стеке, зная, как выпустить ресурсы в конкретном обработчике исключений.
'try-with-resources', кажется, лучший подход, так как он требует меньше кода – superbob
@superbob это лучший подход по нескольким причинам, чем просто« меньше кода »:). – Tom