/ / Изключение от ресурс в близост най-накрая крие друг - на кого му пука? - java, обработка на изключения, java-io

Изключение от ресурс близо до накрая крие друг - кой го е грижа? - Java, обработка на изключения, java-io

Първо, съжалявам, че зададохте въпроса какво трябвабъде добре износена тема. Натъкнах се на множество въпроси с отговори, които предполагат да преглътна (улавя и игнорира / регистрира) потенциално изключение от методи, които затварят ресурси в крайна сметка. Изглежда, това е общоприет модел. Но все още не съм виждал някой да обяснява защо, Ето само един пример: Опитайте-хвана-накрая и след това отново опитайте улов.

Разбрах, че всяко изключение, хвърлено от най-накрая блок, ще "маскира" всяко изключение, хвърлено в съответния пробен блок, но не виждам защо това е лошо нещо. Например:

Resource r = new Resource();
try {
r.use();
other();
} finally {
r.close();
}

Сегашното ми разбиране е:

  1. Ако само close хвърля изключение, определено не искаме да го преглътнем.
  2. Ако и двете use и close хвърлете изключение, вероятно е по същата основна причина и няма значение кое изключение се разпространява (и двамата биха съдържали еднакво полезна информация?).
  3. Ако и двете other и close хвърлете изключение, има два несвързани проблема. Може би този, който се е случил първо, трябва да се разпространява, но няма причина да предполага, че първото изключение причинен второто (има ли?), така че и двете ще направят.

За какво греша?

Отговори:

3 за отговор № 1

Ако изключение хвърля само близко, определено не искаме да го преглътнем.

Това е вярно!

Ако и двамата използват и затварят изключение, това вероятно е по една и съща основна причина и няма значение кое изключение се разпространява (и двете биха съдържали еднакво полезна информация?).

Не точно. Изключението в try можеше да бъде NullPointerException, OutOfMemoryError или действително изключение на I / O, описващо естеството на проблема. Дори и да е изключение за I / O, грешката може да остави потока в непоследователно състояние (или дори да го затвори преждевременно). close() може да отстъпи напълно различна грешка, като „потокът вече е затворен","вътрешна грешка" или каквото и да е.

Една грешка в системата има тенденция да каскадира десеткина други, понякога изглеждат много несвързани. Винаги търсете първото изключение за първопричината. Останалото е просто боклук. Добър пример е инициализация, която се провали и остави обект в непоследователно състояние. По-късно виждате NullPointerExceptionе навсякъде, но истинският проблем възникна по-рано.

Ако и други, и близки хвърлят изключение, има два несвързани проблема. [...] няма някаква причина да се предполага, че първото изключение е причинило второто (има ли?), така че и двете ще го направят.

Всъщност, и двете изключения са вносът, но първият вероятно е по-подходящ. Решение? употреба AutoCloseable ресурси в Java 7 и идиома с опитни ресурси, Ако по време на почистване възникне изключение, то ще бъде прикрепено към първоначалното изключение като подтиснат:

class Resource implements AutoCloseable  //...

и тогава:

try(Resource r = new Resource()) {
r.use();
other();
}

Изключението ще изглежда така:

MyException: Exception in use()
at Resource.use(Main.java:11)
at Main.main(Main.java:16)
Suppressed: java.lang.RuntimeException: Exception in close()
at Main.close(Main.java:6)
at Main.main(Main.java:17)
}