Разница между попыткой наконец и попыткой поймать

какая разница между

try {
    fooBar();
} finally {
    barFoo();
}

и

try {
  fooBar();
} catch(Throwable throwable) {
    barFoo(throwable); // Does something with throwable, logs it, or handles it.
}

Мне больше нравится вторая версия, потому что она дает мне доступ к Throwable. Есть ли какое-либо логическое различие или предпочтительное соглашение между двумя вариантами?

Кроме того, есть ли способ получить доступ к исключению из предложения finally?


person Vijay Kotari    schedule 18.05.2010    source источник


Ответы (11)


Это две разные вещи:

  • Блок catch выполняется только в том случае, если в блоке try выбрасывается исключение.
  • Блок finally выполняется всегда после блока try (-catch), независимо от того, возникло ли исключение.

В вашем примере вы не показали третью возможную конструкцию:

try {
    // try to execute this statements...
}
catch( SpecificException e ) {
    // if a specific exception was thrown, handle it here
}
// ... more catches for specific exceptions can come here
catch( Exception e ) {
    // if a more general exception was thrown, handle it here
}
finally {
    // here you can clean things up afterwards
}

И, как говорит @codeca в своем комментарии, нет возможности получить доступ к исключению внутри блока finally, потому что блок finally выполняется, даже если нет исключения.

Конечно, вы можете объявить переменную, которая содержит исключение за пределами вашего блока, и присвоить значение внутри блока catch. После этого вы можете получить доступ к этой переменной внутри вашего блока finally.

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}
person tangens    schedule 18.05.2010
comment
Следствием этого является то, что вы не можете получить доступ к Throwable из блока finally, потому что может не быть Throwable. - person Dean Harding; 18.05.2010

Это не вариации, это принципиально разные вещи. finally выполняется всегда, catch только при возникновении исключения.

person Michiel Buddingh    schedule 18.05.2010

Наконец и блоки catch совершенно разные:

  • В блоке catch вы можете ответить на возникшее исключение. Этот блок выполняется, только если есть необработанное исключение и тип соответствует одному или является подклассом того, который указан в параметре блока catch.
  • Наконец, всегда будет выполняться после блоков try и catch, независимо от того, возникло ли исключение.

So

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if ExceptionA 
  // was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in try 
  // and not handled by first catch block
}

отличается от

try {
  //some code
}
finally {
  // Gets executed whether or not 
  // an exception was thrown in try block
}

существенно.

Если вы определяете блок попытки, вы должны определить

  1. один блок finally, или
  2. один или несколько блоков catch, или
  3. один или несколько блоков catch и один блок finally

Таким образом, следующий код также будет действительным:

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if 
  // ExceptionA was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in 
  // try and not handled by first catch block
}
//even more catch blocks
finally {
  // Gets executed whether or not an 
  // exception was thrown in try block
}
person TheMorph    schedule 18.05.2010

try используется для запуска метода, который может вызвать исключение

catch используется, чтобы остановить это исключение

finally используется для любой очистки, необходимой после того, как исключение было перехвачено или нет.

try{
    myObject.riskyMethod(); // run a method that may throw an exception
}
catch(Exception ex){
    myLogger.log(ex.Message); // "catch" stop that exception
}
finally{
    myObject = null; // clean up needed from that exception being caught
}
person Kieran    schedule 18.05.2010

try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. Все операторы try должны включать либо одно предложение catch, либо предложение finally.
  2. Он может иметь несколько предложений catch, но только одно предложение finally.
  3. Во время любого выполнения, если возникают какие-либо ошибки, тогда Control передается соответствующему блоку Catch и выполняет операторы, а блок finally выполняется.

Неважно, что блок finally выполняется всегда, так что в целом блок finally используется, когда у вас есть сеансы, подключения к базе данных или файлы или сокеты, тогда будет размещен код для закрытия этих подключений. Это просто для того, чтобы в приложении не было утечек памяти или каких-либо других проблем.

person gmhk    schedule 18.05.2010

Наконец и блоки catch совершенно разные:

В блоке catch вы можете ответить на возникшее исключение. Этот блок выполняется только в том случае, если есть необработанное исключение и тип соответствует одному или является подклассом того, который указан в параметре блока catch. Наконец, всегда будет выполняться после блоков try и catch, независимо от того, возникло ли исключение.

person Android Tutorial    schedule 11.02.2016

В моем исследовании блок finally всегда выполняется, и он в основном «используется для закрытия любых открытых соединений» и уничтожения того, что работает без надобности.

person Hari krishna    schedule 14.10.2015

Обычно, когда мы используем какие-либо ресурсы, такие как потоки, соединения и т. Д., Мы должны закрывать их явно с помощью блока finally. В приведенной ниже программе мы читаем данные из файла с помощью FileReader и закрываем его с помощью блока finally.

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]){
      FileReader fr=null;       
      try{
         File file=new File("file.txt");
         fr = new FileReader(file);  char [] a = new char[50];
         fr.read(a); // reads the content to the array
         for(char c : a)
         System.out.print(c); //prints the characters one by one
      }catch(IOException e){
          e.printStackTrace();
       }
       finally{ 
          try{
              fr.close();
          }catch(IOException ex){       
               ex.printStackTrace();
           }
       }
    }

}

Может быть, другие ребята вроде меня искали что-то подобное.

Информация с этой страницы tutpoint

person Community    schedule 12.09.2016

Блок finally всегда выполняется. Блок Catch выполняется только тогда, когда улавливается исключение, соответствующее параметру блоков.

person mkorpela    schedule 18.05.2010

Даже в первой форме вы можете зарегистрировать это в вызывающем методе. Таким образом, нет большого преимущества, если вы не хотите прямо сейчас заниматься чем-то особенным.

person fastcodejava    schedule 27.08.2010

Блок try будет содержать операторы, которые будут вызывать исключение. Блок catch будет содержать ссылку, брошенную из блока try, а необходимые сообщения генерируются из блока catch. Блок finally также используется для закрытия используемых ресурсов, таких как закрытие io, закрытие файла, закрытие дБ. В Java -9 появился расширенный ресурс try-with, когда ресурсы объявлены вне try..in enchanced try with resource блок catch является обязательным

person srinija    schedule 19.09.2019