Algo chato que tínhamos que fazer nas versões anteriores de Java era o tratamento individual de cada exceção ou utilizar uma classe mais abrangente (Exception, por exemplo) para realizar o tratamento de todas as possíveis exceções. Nessa versão podemos colocar dentro de um único catch, várias Exceptions apenas separando pelo "ou" (pipe "|"). De maneira sucinta, podemos transformar isso:
try { System.out.println(10 / 0); } catch (ArithmeticException e) { System.out.println("Erro: " + e.getMessage()); } catch (IllegalArgumentException e) { System.out.println("Erro: " + e.getMessage()); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Erro: " + e.getMessage()); }
No seguinte código:
try { System.out.println(10 / 0); } catch (ArithmeticException | IllegalArgumentException | ArrayIndexOutOfBoundsException e) { System.out.println("Erro: " + e.getMessage()); }
Pontos importantes:
- A variável declarada dentro do catch é sempre final. Ou seja, não podemos atribuir valores à ela.
- Como nas outras versões do Java, as variáveis dentro do catch precisam ser filhas de Throwable
- Se mais de uma variável for declarada, elas não podem ser do mesmo subtipo da outra. Por exemplo: se A está declarada FilhaDeA (extends A) não pode ser declarada no mesmo catch.
Portanto o seguinte código não compila:
try { int a = 0; if(a==0) { throw new FilhaDeA(); } else { throw new A(); } } catch (FilhaDeA | A e) { System.out.println("Erro: " + e.getMessage()); }
Como FilhaDeA é filha da classe A (extends A), todas as exceções do tipo A (inclusive FilhaDeA) já são capturadas com a declaração de A no catch. Por esse motivo o código não é compilável.
Dessa maneira o tratamento de erros se torna mais simplificado e melhora a legibilidade de código.