Что такое подавленные исключения
Что такое подавленное исключение?
Комментарий (от пользователя soc) к ответ на в вопросе об оптимизации хвостового вызова упоминалось, что в Java 7 есть новая функция, называемая» подавленные исключения «, из-за» добавления ARM «(поддержка процессоров ARM?).
Что в этом контексте означает «подавленное исключение»? В других контекстах «подавленное исключение» было бы исключением, которое было перехвачено, а затем проигнорировано (редко бывает хорошей идеей); это явно что-то другое.
8 ответов
Я считаю, что комментатор имеет в виду исключение, которое наполовину игнорируется, когда оно выбрасывается в неявном блоке finally элемента try-with-resources блок в контексте существующего исключения, генерируемого из блока try :
Исключение может быть вызвано из блока кода, связанного с оператором try-with-resources. В примере writeToFileZipFileContents исключение может быть вызвано из блока try, и до двух исключений могут быть выброшены из оператора try-with-resources, когда он пытается закрыть объекты ZipFile и BufferedWriter. Если исключение выбрасывается из блока try и одно или несколько исключений выбрасываются из оператора try-with-resources, тогда эти исключения, созданные из оператора try-with-resources, подавляются, и исключение, созданное блоком, является единственным вызывается методом writeToFileZipFileContents. Вы можете получить эти подавленные исключения, вызвав метод Throwable.getSuppressed из исключения, созданного блоком try.
(Здесь цитируется раздел «Подавленные исключения» на связанной странице.)
Я думаю, что это связано с «механизмом цепных исключений». Это повлияет на то, как исключение обрабатывается этим средством по мере развития трассировки стека. Со временем исключения, которые являются частью группы связанных исключений, могут быть подавлены. Дополнительные сведения см. В документации по Throwable.
Возьмем очень простой пример
Поскольку функция java 7 была предоставлена для извлечения подавленных исключений. Вы можете вызвать функцию public final java.lang.Throwable[] getSuppressed() для захваченного метательного объекта, чтобы просмотреть подавленные исключения.
Я скомпилировал большинство возможных сценариев с фрагментами кода и вывел их в следующем посте.
Надеюсь, это поможет.
Вы также можете подавить исключения в Java 6 (небольшая хитрость),
Я создал утилиту, которая прозрачно обрабатывает подавление исключений в Java 1.6 и Java 1.7. Вы можете найти реализацию здесь
Все, что вам нужно, это позвонить:
Подавить исключение и
Чтобы получить подавленные исключения Exception, если кто-то все еще использует Java 1.6
Взглянув на байт-код фрагмента примера кода «попробуйте с ресурсами», стандартный обработчики исключений JVM используются для обеспечения семантики «попытка с ресурсами».
Со всеми строками вы получите: java.lang.RuntimeException: from finally!
До Java7; В коде есть исключения, которые каким-то образом игнорируются.
В класс Throwable в JDK 7 были добавлены новый конструктор и два новых метода. Вот как это показано ниже:
С этим новым подходом мы также можем обрабатывать эти подавленные исключения.
В Java7 попробуйте с ресурсами; исключение в AutoCloseable :: close () добавляется как подавленное исключение по умолчанию вместе с исключением try.
Также имейте в виду, что это отличается от связанных исключений (были введены в JDK 1.4 и предназначались чтобы можно было легко отслеживать причинно-следственные связи между исключениями.)
Компилятор должен определить, что из этого «действительно» выбросить. Он выбирает сгенерировать исключение, вызванное явным кодом (код в блоке try ), а не исключение, вызванное неявным кодом (блок finally ). Поэтому исключение (я), созданное в неявном блоке, подавляется (игнорируется). Это происходит только в случае нескольких исключений.
Инструкция try-with-resources в Java
Вступление
Синтаксис
То, как Java понимает этот код:
До внедрения этого подхода закрытие ресурсов выполнялось вручную, как показано в предыдущем коде. По сути, это был стандартный код, и базы кода были завалены ими, что снижало читаемость и затрудняло их обслуживание.
catch и наконец часть попробуйте с ресурсами работают, как ожидалось, с catch блоками, обрабатывающими соответствующие исключения, и наконец блок выполняется независимо от того, было ли исключение или нет. Единственное отличие-это подавленные исключения, которые объясняются в конце этой статьи.
Множество Ресурсов
Еще одним хорошим аспектом попробуйте с ресурсами является простота добавления/удаления ресурсов, которые мы используем, с гарантией того, что они будут закрыты после того, как мы закончим.
Если бы мы хотели работать с несколькими файлами, мы бы открыли файлы в инструкции try() и разделили их точкой с запятой:
Поддерживаемые Классы
Это, конечно, включает в себя определенные пользователем объекты, реализующие Автоклавируемый интерфейс. Однако вы редко столкнетесь с ситуацией, когда захотите написать свои собственные ресурсы.
Обработка исключений
Представьте себе ситуацию:
Важно понимать, что порядок исполнения:
Например, вот ресурс, который ничего не делает, кроме как создает исключения:
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Подсказка : Внезапно исключения, возникающие при закрытии ресурсов, становятся важными.
Помните, что внутри блока try может быть создано только одно исключение. Как только возникает исключение, код блока try завершается, и Java пытается закрыть ресурсы.
Вывод
Код более читабелен, его легче изменять и поддерживать, и обычно он короче.
Что такое подавленное исключение?
Комментарий (пользователь soc) в ответ на вопрос об оптимизации хвостовых опций упоминал, что Java 7 имеет новую функцию, называемую «подавленные исключения», из-за «добавления ARM» (поддержка процессоров ARM?).
Что такое «исключенное исключение» в этом контексте? В других контекстах «исключенное исключение» было бы исключением, которое было поймано, а затем проигнорировано (редко хорошая идея); это явно что-то другое.
ОТВЕТЫ
Ответ 1
Я полагаю, что комментатор ссылается на это исключение, которое игнорируется, когда оно выбрано внутри неявного блока finally try-with-resources, в контексте того, что существующее исключение выбрано из блока try :
Исключение может быть выбрано из блока кода, связанного с оператором try-with-resources. В примере writeToFileZipFileContents исключение может быть выбрано из блока try, и до двух исключений может быть выбрано из инструкции try-with-resources при попытке закрыть объекты ZipFile и BufferedWriter. Если исключение выбрано из блока try, и одно или несколько исключений выбрасываются из оператора try-with-resources, то те исключения, которые выбраны из инструкции try-with-resources, подавляются, а исключение, созданное блоком, является тем, который вызывается методом writeToFileZipFileContents. Вы можете получить эти подавленные исключения, вызвав метод Throwable.getSuppressed из исключения, созданного блоком try.
(Это цитирует раздел «Подавленные исключения» на связанной странице.)
Ответ 2
Компилятор должен определить, какой из них «действительно» бросить. Он выбирает исключение, выраженное в явном коде (код в блоке try ), а не в том, что выбрано неявным кодом (блок finally ). Поэтому исключение (исключения), которое бросается в неявный блок, подавляется (игнорируется). Это происходит только в случае нескольких исключений.
Ответ 3
До Java7; В коде есть исключения, которые были проигнорированы.
В класс Throwable в JDK 7 был добавлен новый конструктор и два новых метода. Они приведены ниже:
с помощью этого нового подхода мы также справимся с этим исключенным исключением.
В Java7 try-with-resources; исключение в AutoCloseable:: close() добавляется как исключенное исключение по умолчанию вместе с исключением try.
Также известно, что это отличается от цепочки исключений (были введены с JDK 1.4 и были предназначены для того, чтобы можно было легко отслеживать причинно-следственные связи между исключениями.)
Ответ 4
Подавленные исключения являются дополнительными исключениями, которые происходят в инструкции try-with-resources (представленный в Java 7), когда AutoCloseable ресурсы закрыты. Поскольку при закрытии ресурсов AutoCloseable могут возникать множественные исключения, дополнительные исключения исключаются из в качестве исключенных исключений.
Ответ 5
Выполнение кода ниже:
Со всеми строками вы получите: java.lang.RuntimeException: from finally!
Удаление блока finally вы получите: java.lang.RuntimeException: from catch!
Удаление блока catch вы получите:
Ответ 6
Я думаю, что это связано с «цепным средством исключения». Это повлияет на то, каким образом исключение обрабатывается этим средством по мере развития трассировки стека. Со временем исключения, которые являются частью группы связанных исключений, могут быть подавлены. Подробнее см. Throwable documentation.
Ответ 7
Возьмем очень простой пример
Я собрал большинство возможных сценариев с фрагментами кода и выводами в следующем сообщении.
Надеюсь, что это поможет.
Ответ 8
Вы также можете подавлять исключения на Java 6 (вовлеченный небольшой обман),
Я создал утилиту, которая прозрачно обрабатывает исключение исключения в Java 1.6 и Java 1.7. Вы можете найти реализацию здесь
Все, что вам нужно, это позвонить:
чтобы исключить исключение, и
чтобы получить исключенные исключения из Exception, если кто-либо еще использует Java 1.6
Одним из основных нововведений, которые были включены в Java 7, стало введение нового оператора «try c ресурсами». «try c ресурсами» это оператор try, в котором объявляются один или несколько ресурсов. Ресурс — это объект, который должен быть закрыт после того, как программа закончит с ним работу. «try c ресурсами» берет всю работу по закрытию ресурсов на себя. Прежде, чем подробно его рассмотреть давайте разберемся в причинах, которые вызвали его появление.
Закрытие ресурсов до Java 7.
Предположим нам нужно написать метод, который считывает первую строчку из одного файла и записывает ее в другой файл. Задача очень простая и ее реализация не должна вызвать каких-либо затруднений:
Слишком много кода для столь простой операции, не находите? Но и это еще не все, в коде выше есть существенный изъян, если при закрытии первого ресурса:
будет сгенерировано исключение, то второй ресурс закрыт не будет:
Самым очевидным выходом из данной ситуации – будет окружить закрытие ресурсов дополнительными блоками try:
Согласитесь, что выглядит ужасно, но до выхода Java 7 с этим приходилось мириться.
Использование try с ресурсами.
Появление оператора try с ресурсами значительно упростило жизнь программистам, больше не было необходимости громоздить конструкции try/catch в надежде, что ты закрыл все ресурсы и предусмотрел все возможные исключительные ситуации, большую часть этой работы try с ресурсами взял на себя. Рассмотрим его общий вид:
Главное отличие от привычного блока try в круглых скобках, в которых создаются ресурсы, которые впоследствии нужно закрыть, ресурсы будут закрываться снизу-вверх автоматически после завершения работы блока try, т.е. в примере, сначала закроется writer, а потом reader. Ресурсы созданные в блоке try(), в нашем случае reader и writer будут видны только в блоке try, в блоках catch и finally попытка их использования вызовет ошибку компиляции.
При использовании оператора try с ресурсами, совершенно не обязательно использовать блоки catch и finally, они являются опциональными, исходя из этого предыдущий пример можно переписать следующим образом:
Подобный код абсолютно легален и никаких ошибок компиляции не вызовет.
Настало время улучшить наш пример из начала статьи, который копирует первую строчку из одного файла в другой:
Получилось в два раза меньше кода, чем в первоначальном примере.
Интерфейс AutoCloseable.
Для того, чтобы класс можно было использовать в операторе try с ресурсами, он должен реализовывать интерфейс AutoCloseable. Хорошая новость, в том, что сделать это не так уж и сложно – необходимо реализовать всего лишь один метод – public void close() throws Exception.
Как и следовало ожидать сначала выполнился код из блока try, а потом произошло закрытие ресурса, с помощью переопределенного метода close(). Вы наверное заметили, что в примере, метод close() не генерирует и не объявляет никаких исключений, в отличии от метода объявленного в интерфейсе AutoCloseable – это вполне легально, переопределяемый метод может генерировать более конкретные исключения или не генерировать их вовсе. Еще на что хотелось бы обратить пристальное внимание, так это на саму реализацию метода close(). Метод close() не должен содержать никакой бизнес логики, только закрытие ресурсов:
Данный код конечно же скомпилируется, но закрытие ресурсов будет вызывать побочный эффект и изменять значение переменной, чего конечно же нужно избегать.
Подавленные исключения.
Подавленные исключения (suppressed exception) образуются, когда в блоке try генерируется исключение и в методе close() при закрытии ресурса генерируется исключение, в этом случае первое исключение считается главным остальные подавленные, чтобы было понятнее рассмотрим пример:
Вывод:
Main exception
Suppressed Exception
Suppressed Exception
В нашем случае получился следующий ход выполнения программы: сначала создаются два объекта Example ex1 и ex2, после чего происходит вход в блок try, где генерируется исключение, программа прекращает выполнения кода в блоке и приступает к закрытию ресурсов снизу-вверх. При закрытии каждого из ресурсов в методе close() генерируется еще по одному исключению, которые последовательно добавляются к главному исключению, сгенерированному в блоке try. После того, как ресурсы были закрыты, программа приступает к обработке исключения в блоке catch, где первой строчкой мы выводим информацию о главном исключении, а последующим циклом получаем подавленные исключения и выводим информацию о них.
Последнее на что стоит обратить внимание, так это, что подавленные исключения работают только в блоке try, в следующем примере будет сгенерировано два самостоятельных и независимых друг от друга исключения:
Что такое подавленное исключение?
комментарий (пользователем soc) на ответ to вопрос об оптимизации хвостового вызова упомянуто, что Java 7 имеет новую функцию, называемую «подавленными исключениями», из-за» добавления ARM » (поддержка процессоров ARM?).
Что такое «подавленное исключение» в этом контексте? В других контекстах «подавленное исключение» было бы исключением, которое было поймано, а затем проигнорировано (редко хорошая идея); это явно что-то отличающийся.
8 ответов
Я считаю, что комментатор ссылается на исключение, которое наполовину игнорируется, когда оно бросается в неявном finally блок try-with-resources блок, в контексте существующего исключения из try блок:
исключение может быть вызвано из блока кода, связанного с инструкцией try-with-resources. В Примере writeToFileZipFileContents из блока try может быть создано исключение и до двух исключения могут быть вызваны из инструкции try-with-resources при попытке закрыть объекты ZipFile и BufferedWriter. Если исключение из try блока и одного или нескольких исключений из try-оператор с ресурсами, то эти исключения из try-оператор с ресурсами подавляются, и исключение в блоке-это одно, что бросается writeToFileZipFileContents способ. Эти подавленные исключения можно получить, вызвав Перекидным.метод getSuppressed из исключения, создаваемого блоком try.
(это цитирование раздела под названием «подавленные исключения» со связанной страницы.)
компилятор должен определить, какой из них» действительно » бросить. Он решает выбросить исключение, вызванное в явном коде (код в try заблокировать) вместо того, чтобы бросать неявный код ( finally блок). Поэтому исключения, создаваемые в неявном блоке, подавляются (игнорируются). Это происходит только в случае нескольких исключений.
перед Java7; в коде есть исключения, но они были проигнорированы каким-то образом.
новый конструктор и два новых метода были добавлены в класс Throwable в JDK 7. Это, как показано ниже:
С этим новым подходом мы также можем справиться с этими подавленными исключениями.
В Java7 try-with-resources; исключение в AutoCloseable:: закрыть() по умолчанию добавляется как подавленное исключение вместе с исключением try.
также известно, что это отличается от цепи исключений (были введены с JDK 1.4 и были предназначены, чтобы сделать возможным легко отслеживать причинно-следственные связи между исключениями.)
подавленных исключений являются дополнительными исключениями, которые происходят в инструкции try-with-resources (введено в Java 7) при AutoCloseable ресурсы закрыты. Потому что при закрытии может произойти несколько исключений AutoCloseable ресурсы, дополнительные исключения прилагаются к первичное исключение как подавленные исключения.
глядя на байт-код фрагмента образца кода try-with-resources, standard в JVM обработчики исключений используются для размещения семантики try-with-resources.
Concedering код ниже:
со всеми линиями, вы получите: java.lang.RuntimeException: from finally!
удаление finally блок вы получите: java.lang.RuntimeException: from catch!
удаление catch блок вы получите:
Я думаю, что это связано с «прикованным средством исключения». Это повлияет на то, как исключение обрабатывается этим средством по мере развития трассировки стека. Со временем исключения, входящие в группу связанных исключений, могут быть подавлены. Посмотреть Throwable documentation для более подробной информации.
вы также можете подавлять исключения в Java 6 (немного обмана),
Я создал утилиту, которая прозрачно обрабатывает подавление исключений в Java 1.6 и Java 1.7. Вы можете найти реализацию здесь
все, что вам нужно, это позвонить:
чтобы подавить исключение, и
чтобы получить подавленные исключения исключения, в случае, если кто-то все еще использует Java 1.6
ARM-автоматическое управление ресурсами (введено с Java 7)