Pergunta

Qual é a diferença entre

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

e

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

Eu gosto mais da segunda versão porque me dá acesso ao jogável. Existe alguma diferença lógica ou uma convenção preferida entre as duas variações?

Além disso, existe uma maneira de acessar a exceção da cláusula finalmente?

Foi útil?

Solução

Estas são duas coisas diferentes:

  • O bloco de captura é executado apenas se uma exceção for lançada no bloco de tentativas.
  • O bloco finalmente é executado sempre após o bloco de tentativa (--t-capat), se uma exceção for lançada ou não.

No seu exemplo, você não mostrou a terceira construção possível:

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
}

E, como @Codeca diz em seu comentário, não há como acessar a exceção dentro do bloco finalmente, porque o bloco finalmente é executado mesmo que não haja exceção.

É claro que você pode declarar uma variável que mantém a exceção fora do seu bloco e atribui um valor dentro do bloco de captura. Depois, você pode acessar essa variável dentro do seu bloco finalmente.

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}

Outras dicas

Essas não são variações, são coisas fundamentalmente diferentes. finally É executado sempre, catch Somente quando ocorre uma exceção.

Finalmente e os blocos de captura são bem diferentes:

  • Dentro do bloco de captura, você pode responder à exceção jogada. Este bloco é executado apenas se houver uma exceção não tratada e o tipo corresponde a um ou é subclasse do especificado no parâmetro do bloco de captura.
  • Finalmente será sempre executado Depois de experimentar, capturar blocos, se há uma exceção levantada ou não.

Então

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
}

é diferente de

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

significativamente.

Se você definir um bloco de tentativa, você terá que definir

  1. um finalmente bloco, ou
  2. um ou mais blocos de captura, ou
  3. um ou mais blocos de captura e um finalmente bloco

Portanto, o código a seguir também seria válido:

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
}
try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. Todas as declarações de tentativa devem incluir uma cláusula de captura ou uma cláusula finalmente
  2. Pode ter uma cláusula de captura múltipla, mas apenas uma cláusula finalmente
  3. Durante qualquer execução, se ocorrer algum erro, o controle será transferido para o bloco de captura apropriado e executa as instruções e, finalmente, o bloco é executado.

Não importa o que o bloco finalmente seja executado, portanto, em geral, finalmente é usado o bloco, quando você tem sessões, conexões de banco de dados ou arquivos ou soquetes estão abertos, o código para fechar essas conexões será colocado. Isso é apenas para garantir que, em um aplicativo, não haja vazamentos de memória ou outros problemas não devem ocorrer.

Finalmente e os blocos de captura são bem diferentes:

Dentro do bloco de captura, você pode responder à exceção jogada. Esse bloco é executado apenas se houver uma exceção não atendida e o tipo corresponder a um ou subclasse do especificado no parâmetro do bloco de captura. Finalmente, será sempre executado após a tentativa de obter blocos, se houver uma exceção levantada ou não.

Tente é usado para executar um método que pode lançar uma exceção

A captura é usada para "pegar" parar essa exceção

finalmente é usado para qualquer limpeza necessária a partir dessa exceção sendo pega ou não

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
}

Na minha pesquisa, finalmente é executado o bloco de pesquisa e é "usado principalmente para as conexões abertas para fechar" e destruir algo que está sendo executado desnecessariamente.

Finalmente, o bloco é sempre executado. O bloco de captura é executado apenas quando uma exceção que corresponde ao parâmetro Blocks é capturada.

Mesmo na primeira forma, você pode registrá -lo no método de chamada. Portanto, não há grande vantagem, a menos que você queira fazer um manuseio especial ali.

Geralmente, quando usamos recursos como fluxos, conexões etc. Temos que fechá -los explicitamente usando o bloqueio finalmente. No programa fornecido abaixo, estamos lendo dados de um arquivo usando o FileReader e estamos fechando -os usando finalmente o bloco.

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();
           }
       }
    }

}

Talvez outros caras como eu procurassem algo assim.

Informações desta página Tutpoint

O Bloco de Tente realizará as declarações que aumentarão a exceção. O bloco de captura manterá a referência lançada do bloco de tentativa e as mensagens necessárias são geradas a partir do bloco de captura. Finalmente, o bloco também é usado para fechar os recursos usados, como fechamento de IO, fechamento de arquivos, fechamento de db. Em Java -9, surgiram recursos de tentativa e menos, onde os recursos são declarados fora da tentativa. é mandatório

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top