В общем случае метод Throwable addSuppressed()
следует использовать, когда каким-либо образом мы имеем параллельное выполнение, которое может вызвать исключение, когда подавляет .Я нашел 2 примера:
блок Try-with-resource (блок try-finally), когда вызывающий код будет видеть исходное исключение (в блоке try или catch) и исключение, котороеслучилось в блоке, наконец.
пакетных заданий (массовые операции), когда мы должны перейти к следующему элементу независимо от того, была ли успешной операция с текущим элементом
Прежде чем перейти к деталям, как сказал @sarelbotha, в моем случае мне просто нужно продолжать оборачивать исходное исключение как причину моего нового исключения.
Поведение по умолчанию в блоке try-finally,где у нас есть 2 исключения, то исходное исключение подавлено , и мы видим только исключение из блока finally.Если мы используем блок finally для того, чтобы закрыть ресурс, мы действительно хотим увидеть исходное исключение, но при желании мы хотим также видеть исключения из блока finally, который закрыл наш ресурс и завершился неудачей.
Начиная с версии 7 платформа поддерживает понятие исключенных исключений (в сочетании с оператором try-with-resources).Любые исключения, которые были подавлены для доставки исключения, распечатываются под трассировкой стека.
http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#printStackTrace%28%29
Сначала следует прочитать о новой возможности try-with-resource.Вы можете прочитать его здесь http://www.baptiste -wicht.com / 2010/08 / java-7-try-with-resources-Statement / , например или здесь Что такое Java 7 try-with-ресурсный эквивалент байт-кода с использованием try-catch-finally? .Короче говоря, вы можете иметь 2 Throwable параллельно в некотором смысле, обычно от блока try и от блока finally.Старая семантика try-catch будет возвращать исключение из блока finally, тогда как исключено исключение из блока try (или повторно выбрасывать исключение из блока catch).Новая функция try-with-resource позволяет получить оба исключения.Более того, вы получите исходное исключение, где исключение из блока finally будет подавлено
Обратите внимание, что когда одно исключение вызывает другое исключение, первое исключение обычно перехватывается, а затемвторое исключение выдается в ответ.Другими словами, существует причинно-следственная связь между двумя исключениями.Напротив, существуют ситуации, когда два независимых исключения могут быть сгенерированы в блоках кода одного уровня, в частности в блоке try оператора try-with-resources и сгенерированном компилятором блоке finally, который закрывает ресурс.В этих ситуациях может распространяться только одно из сгенерированных исключений.В инструкции try-with-resources, когда есть два таких исключения, исключение, происходящее из блока try, распространяется, и исключение из блока finally добавляется в список исключений, подавленных исключением из блока try.Поскольку исключение раскручивает стек, оно может накапливать несколько исключенных исключений.
Пример:
public class TestClass {
static class ResourceA implements AutoCloseable{
public void read() throws Exception{
throw new Exception("ResourceA read exception");
}
@Override
public void close() throws Exception {
throw new Exception("ResourceA close exception");
}
};
static class ResourceB implements AutoCloseable{
public void read() throws Exception{
throw new Exception("ResourceB read exception");
}
@Override
public void close() throws Exception {
throw new Exception("ResourceB close exception");
}
};
//a test method
public static void test() throws Exception{
try (ResourceA a = new ResourceA();
//ResourceB b = new ResourceB()
) {
a.read();
//b.read();
} catch (Exception e) {
throw e;
}
}
public static void main(String[] args) throws Exception {
test();
}
}
Вывод будет следующим:
Exception in thread "main" java.lang.Exception: ResourceA read exception
at TestClass$ResourceA.read(TestClass.java:6)
at TestClass.test(TestClass.java:29)
at TestClass.main(TestClass.java:39)
Suppressed: java.lang.Exception: ResourceA close exception
at TestClass$ResourceA.close(TestClass.java:10)
at TestClass.test(TestClass.java:31)
... 1 more
пакетные задания (массовые операции). Ну, я нашел некоторое использование этого метода за пределами try-with-resources.Ниже приведен исходный код из java.net.URLClassLoader.close
public void close() throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(new RuntimePermission("closeClassLoader"));
}
List<IOException> errors = ucp.closeLoaders();
// now close any remaining streams.
synchronized (closeables) {
Set<Closeable> keys = closeables.keySet();
for (Closeable c : keys) {
try {
c.close();
} catch (IOException ioex) {
errors.add(ioex);
}
}
closeables.clear();
}
if (errors.isEmpty()) {
return;
}
IOException firstex = errors.remove(0);
// Suppress any remaining exceptions
for (IOException error: errors) {
**firstex.addSuppressed(error);**
}
throw firstex;
}
В общем, такой подход можно использовать в пакетных заданиях (массовые операции), когда мы должныпереходите к следующему элементу (закрывая следующие открытые потоки, как в этом примере) независимо от того, была ли успешной операция с текущим элементом или нет.Таким образом, мы имеем, как я уже говорил, каким-то образом параллельное выполнение, которое может вызвать исключение, когда подавляет .В таких случаях мы должны использовать описанный выше подход, чтобы вызвать исключение с оставшимся подавленным исключением.