Исключение из метода close() в try-with-resource
Я читал о try-in-resource в JDK7, и пока я думал о том, чтобы обновить мое приложение для работы с JDK7, я столкнулся с этой проблемой.
При использовании BufferedReader, например, write throws IOException и close throws IOException.. в блоке catch я заинтересован в исключении IOException, которое вы выбрали для записи. Но мне было бы все равно, если вы закроете закрытие..
Такая же проблема с подключением к базе данных.. и любой другой ресурс..
В качестве примера я создал автоматически закрытый ресурс:
public class AutoCloseableExample implements AutoCloseable {
public AutoCloseableExample() throws IOException{
throw new IOException();
}
@Override
public void close() throws IOException {
throw new IOException("An Exception During Close");
}
}
Теперь при использовании:
public class AutoCloseTest {
public static void main(String[] args) throws Exception {
try (AutoCloseableExample example = new AutoCloseableExample()) {
System.out.println(example);
throw new IOException("An Exception During Read");
} catch (Exception x) {
System.out.println(x.getMessage());
}
}
}
как я могу различать такие исключения, не создавая обертки для классов, таких как BufferedReader?
В большинстве случаев я помещаю ресурс в try/catch внутри блока finally, не заботясь о его обработке.
Ответы
Ответ 1
Рассмотрим класс:
public class Resource implements AutoCloseable {
public Resource() throws Exception {
throw new Exception("Exception from constructor");
}
public void doSomething() throws Exception {
throw new Exception("Exception from method");
}
@Override
public void close() throws Exception {
throw new Exception("Exception from closeable");
}
}
и блок try-with-resource:
try(Resource r = new Resource()) {
r.doSomething();
} catch (Exception ex) {
ex.printStackTrace();
}
1. Разрешены все 3 оператора броска.
Сообщение "Исключение из конструктора" будет напечатано, а исключение, созданное конструктором, будет подавлено, это означает, что вы не можете его поймать.
2. Конструктор throw in удален.
Теперь трассировка стека будет печатать "Исключение из метода" и "Подавлено: исключение из закрываемого" ниже. Здесь вы также не можете поймать исключенное исключение, созданное методом close, но вам будет отказано в исключенном исключении.
3. Выбрасывается из конструктора и метода.
Как вы, наверное, уже догадались, будет напечатан "Исключение из закрываемого".
Важный совет: Во всех вышеперечисленных ситуациях вы на самом деле ловите все исключения, независимо от того, где они были выброшены. Поэтому, если вы используете блок try-with-resource, вам не нужно обертывать блок с помощью другого try-catch, это просто бесполезно.
Надеюсь, это поможет:)
Ответ 2
Я бы предложил использовать флаг, как в следующем примере:
static String getData() throws IOException {
boolean isTryCompleted = false;
String theData = null;
try (MyResource br = new MyResource();) {
theData = br.getData();
isTryCompleted = true;
} catch(IOException e) {
if (!isTryCompleted )
throw e;
// else it a close exception and it can be ignored
}
return theData;
}
source: Закрыть ресурс тихо используя try-with-resources