1. Exceções
>
Por fim, os programadores pensaram em padronizar e automatizar o tratamento de erros. Isso aconteceu quando as exceções foram inventadas. Agora, o mecanismo de exceção lida com 80% das situações excepcionais.
Se algum estudioso apresentou exceções, provavelmente foi o assunto de sua dissertação de doutorado. Se um programador surgiu com isso, então ele pode ter recebido um tapinha amigável nas costas de um colega de trabalho: "Parece bom, mano."
Quando ocorre um erro em um programa Java, como a divisão por 0
, algumas coisas maravilhosas acontecem:
Passo um
Um objeto de exceção especial é criado, contendo informações sobre o erro ocorrido.
Tudo em Java é um objeto, e exceções não são exceções 🙂 Objetos de exceção têm suas próprias classes, e a única coisa que os distingue das classes comuns é que eles herdam a classe Throwable
.
Passo dois
O objeto de exceção é "lançado". Talvez a formulação aqui poderia ser melhor. "Lançar uma exceção" é mais como disparar um alarme de incêndio ou soar um alerta "DEFCON 1".
Quando uma exceção é lançada para a máquina Java, a operação normal do programa é interrompida e os "protocolos de emergência" começam.
Passo três
O método no qual a exceção foi lançada sai imediatamente. A exceção é passada para o método de chamada, que também sai imediatamente. E assim por diante na cadeia até que o main
método saia. Quando o main
método termina, o programa também termina.
Exemplo:
Código | Saída do console |
---|---|
|
|
Uma exceção ocorre na linha 20: divisão por 0. A máquina Java imediatamente cria uma exceção — um ArithmeticException
objeto e o "lança" para o método.
O divide()
método termina imediatamente, então nunca vemos a string: Nothing terrible aconteceu: 0. O programa retorna ao endTheWorld()
método, e a situação se repete: há uma exceção não tratada no sistema, o que significa que o endTheWorld()
método também termina de forma anormal. Em seguida, o main
método termina e o programa para.
Qual é o objetivo dessas exceções? Bem, você pode escrever seu próprio código para capturar determinados tipos de exceções e escrever sua própria lógica para lidar com situações excepcionais.
2. Capturando exceções:try-catch
Java tem um mecanismo de captura de exceção que permite interromper essa finalização anormal de métodos. Se parece com isso:
try
{
// Code where an exception might occur
}
catch(ExceptionType name)
{
// Exception handling code
}
Essa construção é chamada de try-catch
bloco.
O código onde podem ocorrer exceções é colocado entre chaves, precedido pela palavra try
.
Após as chaves, temos a catch
palavra-chave e, entre parênteses, a declaração de uma variável de exceção . Isso é seguido por chaves que envolvem o código a ser executado se ocorrer uma exceção do tipo especificado .
Se nenhuma exceção for lançada durante a execução do " código primário ", o código dentro do bloco catch não será executado. Se ocorrer uma exceção, ela será (se o tipo da exceção lançada for o mesmo que o tipo da variável entre parênteses).
Exemplo:
Código | Saída do console |
---|---|
|
|
3. Múltiplos catch
blocos
Em teoria, todos os tipos de exceções podem ser lançados em um bloco de código. Alguns você vai querer lidar de um jeito, outros de outro jeito, e ainda outros você vai decidir não lidar de jeito nenhum.
Os desenvolvedores Java decidiram ajudá-lo e permitir que você escreva não um, mas muitos catch
blocos após o try
bloco.
try
{
// Code where an exception might occur
}
catch (ExceptionType1 name1)
{
// Code for handling ExceptionType1
}
catch (ExceptionType2 name2)
{
// Code for handling ExceptionType2
}
catch (ExceptionType3 name3)
{
// Code for handling ExceptionType3
}
Exemplo:
Código | Saída do console |
---|---|
|
|
4. Ordem dos catch
blocos
Exceções que ocorrem em um try
bloco só podem ser capturadas por um único catch
bloco. Você não pode ter uma situação de manipulação de exceção em que o código de vários catch
blocos é executado.
Mas a ordem dos blocos é importante.
Você pode ter uma situação em que uma exceção pode ser capturada por vários blocos. Se for esse o caso, a exceção será capturada pelo bloco catch que vier primeiro (mais próximo do try
bloco).
Como você pode ter uma situação em que vários blocos catch podem capturar a mesma exceção?
Todas as exceções pertencem a uma única hierarquia de herança — veja o diagrama.
Um ArithmeticException
objeto pode ser atribuído a uma variável cujo tipo é ArithmeticException
ou qualquer uma de suas classes ancestrais: RuntimeException
, Exception
e Throwable
— veja o diagrama.
Falaremos mais sobre herança e classes ancestrais no Nível 21.
Este código irá compilar perfeitamente:
Benefícios da herança: |
---|
|
Então você pode pegar um ArithmeticException
com qualquer um dos 4 catch
blocos acima.
Exemplo 1:
Código | Saída do console |
---|---|
|
|
Neste exemplo, o ArithmeticException
pode ser capturado pelos blocos catch (Exception e)
e catch (ArithmeticException e)
. Ele será capturado pelo bloco mais próximo do try
bloco - o primeiro catch
bloco.
Para evitar surpresas, é melhor colocar catch
blocos que possam capturar quase todas as exceções perto do final da lista de catch
blocos.
O Throwable
tipo geralmente é capaz de capturar todas as exceções possíveis em Java . Se você colocá-lo no primeiro catch
bloco, o código não será compilado, pois o compilador sabe que existem blocos de código inacessíveis.
GO TO FULL VERSION