Может ли маскировка исключений быть полностью предотвращена с помощью оператора try-with-resources - PullRequest
0 голосов
/ 05 ноября 2018

Мне известно, что оператор try-with-resources был введен для лечения (или) предотвращения маскирования исключений.

Рассмотрим следующий код:

class TestExceptionSuppressing {
    public static void main(String[] args) {
        try {
            testMethod();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            for (Throwable t : e.getSuppressed()) {
                System.err.println("Suppressed Exceptions List: " + t);
            }
        }
    }

    static void testMethod() {
        try (InnerClass inner = new InnerClass()) {
            throw new IOException("Exception thrown within try block");
        } catch (Exception e) {
            throw new RuntimeException(
                    "Exception thrown within catch block.Hence exception thrown within try block will be lost (or) masked");
        }
    }

    static class InnerClass implements AutoCloseable {

        @Override
        public void close() throws Exception {
            throw new Exception("Exception thrown in close method will be tacked on to existing exceptions");
        }
    }
}

Вывод: Исключение, выброшенное в блоке catch. Исключение, выброшенное в блоке try, будет потеряно (или) замаскировано

По-видимому, исключение, выданное в блоке catch метода testMethod (), замаскировало как исключение io, выданное в блоке try, так и исключение, подавленное и добавленное к этому исключению io (выданное в методе close)

Этот пример кода может доказать, что try-with-resources не может полностью предотвратить маскирование исключений.

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

1 Ответ

0 голосов
/ 05 ноября 2018

Вы можете сохранить исходное исключение, если используете RuntimeException (String, Throwable)

Создает новое исключение времени выполнения с указанным подробным сообщением и причиной.

throw new RuntimeException(
                "Exception thrown within catch block  won't be lost (or) masked", e);

Если вы хотите добавить исключенное исключение try и resources, вам нужно использовать метод addSuppressed (Throwable) , в вашем случае:

RuntimeException runtimeException = new RuntimeException(
                    "Exception thrown within try block won't be lost (or) masked", e);
            runtimeException.addSuppressed(e.getSuppressed()[0]);

Дополнительная информация в Исключенные исключения и попытка использования ресурсов

Однако то, что в этом сценарии подавлено исключение CloseException, не означает, что это исключенное исключение было проигнорировано. Чтобы решить эту концепцию подавленных исключений, в Java 7 были добавлены два новых метода и конструктор класса java.lang.Throwable.

public final void addSuppressed(Throwable exception)
...