Что такое исключенное исключение? - PullRequest
65 голосов
/ 21 октября 2011

Комментарий (пользователь soc ) к ответу на на вопрос об оптимизации хвостового вызова упомянул, что в Java 7 появилась новая функция под названием "подавленные исключения"", из-за" добавления ARM "(поддержка процессоров ARM?).

Что такое" исключенное исключение "в этом контексте?В других контекстах «подавленное исключение» было бы исключением, которое было поймано, а затем проигнорировано (редко хорошая идея);это явно что-то другое.

Ответы [ 8 ]

56 голосов
/ 21 октября 2011

Чтобы прояснить цитату в ответе Джона, методом может быть выдано только одно исключение (для каждого выполнения), но в случае try-with-resources возможно создание нескольких исключений.Например, один может быть брошен в блок, а другой может быть брошен из неявного finally, предоставленного try-with-resources.

Компилятор должен определить, какой из них «действительно» выбросить.Он выбирает генерировать исключение, сгенерированное в явном коде (код в блоке try), а не в неявном коде (блок finally).Поэтому исключение (я), выброшенное в неявном блоке, подавляется (игнорируется).Это происходит только в случае нескольких исключений.

50 голосов
/ 21 октября 2011

Я полагаю, что комментатор ссылается на исключение, которое частично игнорируется, когда оно генерируется в неявном блоке 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.

(Это цитирует раздел «Подавленные исключения» со связанной страницы.)

17 голосов
/ 20 ноября 2014

до Java7; В коде есть исключения, но как-то их игнорировали.

например.)

public class SuppressedExceptions {
  public static void main(String[] args) throws Exception {
    try {
        callTryFinallyBlock();
    } catch (Exception e) {
        e.printStackTrace(); **//Only Finally Exception is Caught**
    }
  }

  private static void callTryFinallyBlock() throws Exception {
    try 
    {
        throw new TryException(); **//This is lost**
    }
    finally
    {
        FinallyException fEx = new FinallyException();
        throw fEx;
    }
  }
}

class TryException extends Exception {
}

class FinallyException extends Exception {
}

Новый конструктор и два новых метода были добавлены в класс Throwable в JDK 7. Это как показано ниже:

Throwable.getSupressed(); // Returns Throwable[]
Throwable.addSupressed(aThrowable);

с этим новым подходом мы можем обработать и те исключенные исключения.

public class SuppressedExceptions {
  public static void main(String[] args) throws Exception {
    try {
        callTryFinallyBlock();
    } catch (Exception e) {
        e.printStackTrace();
        for(Throwable t: e.getSuppressed())
        {
            t.printStackTrace();
        }
    }
  }

  private static void callTryFinallyBlock() throws Exception {
    Throwable t = null;
    try 
    {
        throw new TryException();
    }
    catch (Exception e) {
        t = e;
    }
    finally
    {
        FinallyException fEx = new FinallyException();
        if(t != null)fEx.addSuppressed(t);
        throw fEx;
    }
  }
}

class TryException extends Exception {
}

class FinallyException extends Exception {
}

В Java7 try-with-resources; исключение в AutoCloseable :: close () по умолчанию добавляется как исключенное исключение вместе с исключением try.

Также известно, что это отличается от связанных исключений (были введены в JDK 1.4 и предназначались для того, чтобы можно было легко отслеживать причинно-следственные связи между исключениями.)

9 голосов
/ 21 октября 2011

Подавленные исключения - это дополнительные исключения, возникающие в операторе try-with-resources (, введенном в Java 7 ), когда ресурсы AutoCloseable закрыты.Поскольку при закрытии ресурсов AutoCloseable может возникать несколько исключений, дополнительные исключения присоединяются к первичному исключению как подавленные исключения .

Просмотр байт-кода фрагмента примера try-with-resourcesкод, стандартный Обработчики исключений JVM используются для обеспечения семантики попытки с ресурсами.

6 голосов
/ 13 мая 2016

Код с кодом ниже:

public class MultipleExceptionsExample {

   static class IOManip implements Closeable{
       @Override
       public void close() {
           throw new RuntimeException("from IOManip.close");
       }
   }

   public static void main(String[] args) {
       try(IOManip ioManip = new IOManip()){
           throw new RuntimeException("from try!");
       }catch(Exception e){
           throw new RuntimeException("from catch!");
       }finally{
           throw new RuntimeException("from finally!");
       }
   }
}

Со всеми строками вы получите: java.lang.RuntimeException: from finally!

Сняв finally блок, вы получите: java.lang.RuntimeException: from catch!

Сняв catch блок, вы получите:

Exception in thread "main" java.lang.RuntimeException: from try!
    Suppressed: java.lang.RuntimeException: from IOManip.close
0 голосов
/ 11 июня 2014

Вы также можете подавлять исключения в Java 6 (с небольшой хитростью),

Я создал утилиту, которая прозрачно обрабатывает подавление исключений в Java 1.6 и Java 1.7.Вы можете найти реализацию здесь

Все, что вам нужно, это позвонить:

public static <T extends Throwable> T suppress(final T t, final Throwable suppressed) 

для подавления исключения и

public static Throwable [] getSuppressed(final Throwable t) {

дляполучить исключенные исключения исключений, если кто-нибудь все еще использует Java 1.6

0 голосов
/ 17 октября 2013

ARM - Автоматическое управление ресурсами (введено начиная с Java 7)

Возьмите очень простой пример

static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }
}

Теперь, если функция readLine() выдает Exception, а затемдаже close() функция [в блоке finally] выдает исключение, тогда последнему присваивается больший приоритет, и он возвращается к вызывающей функции.В этом случае Exception thrown by the readLine() method is ignored/suppressed.Вы можете зацепить вызывающее исключение в своем исключении и перебросить свое исключение из блока finally.

Поскольку была предоставлена ​​функциональность java 7 для извлечения подавленных исключений.Вы можете вызвать функцию public final java.lang.Throwable[] getSuppressed() на пойманном бросаемом объекте, чтобы просмотреть подавленные исключения.

Например:

static String readFirstLineFromFileWithFinallyBlock(String path)
        throws Exception {
    try (BufferedReader br = new BufferedReader(new FileReader(path));) {
        return br.readLine();
    }
}

Теперь, если br.readLine(); строка выбросит Exception1, а затем скажем,Exception2 выбрасывается при закрытии ресурса [Представьте, что это происходит в неявном блоке finally, который создает оператор try-with-resource], затем Exception1 подавляет Exception2.

Несколько замечаний, которые следует здесь отметить -

  1. Если блок try-with-resource выдает исключение, т. Е. При создании экземпляра ресурса, блок try не будет выполнен, и будет выдано то же исключение.
  2. Если экземпляр ресурса успешен, блок try выдает исключение и исключениегенерируется при закрытии ресурса, затем исключение, генерируемое при закрытии ресурса, подавляется исключением, генерируемым из блока try.
  3. Если вы укажете явный блок finally и из этого блока будет сгенерировано исключение, оно будет подавлять все остальные исключения.(Этот явный блок finally выполняется после закрытия ресурсов)

Я скомпилировал большинство возможных сценариев с фрагментами кода и вывел их в следующем посте.

Подавленные исключения в Java 7

Надеюсь, что поможет.

0 голосов
/ 26 марта 2013

Я думаю, что это связано с "цепочкой исключений". Это повлияет на то, как исключение будет обрабатываться этим средством по мере развития трассировки стека. Со временем исключения, которые являются частью группы связанных исключений, могут быть подавлены. Смотрите Throwable документацию для более подробной информации.

...