Neste tutorial, aprenderemos a lidar com várias exceções em Java com a ajuda de exemplos.
Antes do Java 7, tínhamos que escrever vários códigos de tratamento de exceção para diferentes tipos de exceções, mesmo que houvesse redundância de código.
Vamos dar um exemplo.
Exemplo 1: vários blocos catch
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (ArithmeticException e) ( System.out.println(e.getMessage()); ) catch (ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Resultado
/ por zero
Neste exemplo, duas exceções podem ocorrer:
ArithmeticException
porque estamos tentando dividir um número por 0.ArrayIndexOutOfBoundsException
porque declaramos uma nova matriz inteira com limites de 0 a 9 e estamos tentando atribuir um valor ao índice 10.
Estamos imprimindo a mensagem de exceção em ambos os catch
blocos, ou seja, código duplicado.
A associatividade do operador de atribuição =
é da direita para a esquerda, portanto, um ArithmeticException
é lançado primeiro com a mensagem / por zero.
Lidar com múltiplas exceções em um bloco catch
No Java SE 7 e posterior, agora podemos capturar mais de um tipo de exceção em um único catch
bloco.
Cada tipo de exceção que pode ser tratado pelo catch
bloco é separado por uma barra vertical ou barra vertical |
.
Sua sintaxe é:
try ( // code ) catch (ExceptionType1 | Exceptiontype2 ex) ( // catch block )
Exemplo 2: bloco Multi-catch
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (ArithmeticException | ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Resultado
/ por zero
A captura de várias exceções em um único catch
bloco reduz a duplicação de código e aumenta a eficiência.
O bytecode gerado durante a compilação deste programa será menor do que o programa com vários catch
blocos, pois não há redundância de código.
Nota: Se um catch
bloco lida com várias exceções, o parâmetro catch é implicitamente final
. Isso significa que não podemos atribuir nenhum valor para capturar parâmetros.
Exceção de base de captura
Ao capturar várias exceções em um único catch
bloco, a regra é generalizada para especializada.
Isso significa que, se houver uma hierarquia de exceções no catch
bloco, podemos capturar a exceção base apenas em vez de capturar várias exceções especializadas.
Vamos dar um exemplo.
Exemplo 3: Captura apenas a classe de exceção base
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (Exception e) ( System.out.println(e.getMessage()); ) ) )
Resultado
/ por zero
Sabemos que todas as classes de exceção são subclasses da Exception
classe. Portanto, em vez de capturar várias exceções especializadas, podemos simplesmente capturar a Exception
classe.
Se a classe de exceção base já tiver sido especificada no catch
bloco, não use classes de exceção filho no mesmo catch
bloco. Caso contrário, obteremos um erro de compilação.
Vamos dar um exemplo.
Exemplo 4: captura de classes de exceção base e filha
class Main ( public static void main(String() args) ( try ( int array() = new int(10); array(10) = 30 / 0; ) catch (Exception | ArithmeticException | ArrayIndexOutOfBoundsException e) ( System.out.println(e.getMessage()); ) ) )
Resultado
Main.java:6: erro: Alternativas em uma instrução multi-catch não podem ser relacionadas por subclasses
Neste exemplo, ArithmeticException
e ArrayIndexOutOfBoundsException
são ambas subclasses da Exception
classe. Portanto, obtemos um erro de compilação.