1. Tipos de exceções

Todas as exceções são divididas em 4 tipos, que na verdade são classes que herdam umas das outras.
Throwable
aula
A classe base para todas as exceções é a Throwable
classe. A Throwable
classe contém o código que grava a pilha de chamada atual (rastreamento de pilha do método atual) em uma matriz. Aprenderemos o que é um rastreamento de pilha um pouco mais tarde.
O operador throw só pode aceitar um objeto que deriva da Throwable
classe. E embora você possa teoricamente escrever códigos como throw new Throwable();
, ninguém costuma fazer isso. O principal objetivo da Throwable
classe é ter uma única classe pai para todas as exceções.
Error
aula
A próxima classe de exceção é a Error
classe, que herda diretamente a Throwable
classe. A máquina Java cria objetos da Error
classe (e seus descendentes) quando ocorrem problemas sérios . Por exemplo, um mau funcionamento do hardware, memória insuficiente, etc.
Normalmente, como programador, não há nada que você possa fazer em uma situação em que tal erro (do tipo para o qual um Error
deve ser lançado) tenha ocorrido no programa: esses erros são muito sérios. Tudo o que você pode fazer é notificar o usuário de que o programa está travando e/ou gravar todas as informações conhecidas sobre o erro no log do programa.
Exception
aula
As classes Exception
e RuntimeException
são para erros comuns que acontecem na operação de vários métodos. O objetivo de cada exceção lançada é ser capturado por um catch
bloco que saiba como tratá-la adequadamente.
Quando um método não pode concluir seu trabalho por algum motivo, ele deve notificar imediatamente o método de chamada lançando uma exceção do tipo apropriado.
Em outras palavras, se uma variável for igual a null
, o método lançará um NullPointerException
. Se os argumentos incorretos forem passados para o método, ele lançará um InvalidArgumentException
. Se o método acidentalmente dividir por zero, ele lançará um ArithmeticException
.
RuntimeException
aula
RuntimeExceptions
são um subconjunto de Exceptions
. Poderíamos até dizer que RuntimeException
é uma versão leve das exceções comuns ( Exception
) — menos requisitos e restrições são impostos a tais exceções
Você aprenderá a diferença entre Exception
e RuntimeException
mais tarde.
2. Throws
: exceções verificadas

Todas as exceções Java se enquadram em 2 categorias: marcadas e desmarcadas .
Todas as exceções que herdam o RuntimeException
ou Error
são consideradas exceções não verificadas . Todos os outros são exceções verificadas .
Vinte anos depois que as exceções verificadas foram introduzidas, quase todo programador Java pensa nisso como um bug. Em estruturas modernas populares, 95% de todas as exceções não são verificadas. A linguagem C#, que quase copiou o Java exatamente, não adicionou exceções verificadas .
Qual é a principal diferença entre exceções verificadas e não verificadas ?
Existem requisitos adicionais impostos às exceções verificadas . Grosso modo, são estes:
Requisito 1
Se um método lança uma exceção verificada , ele deve indicar o tipo de exceção em sua assinatura . Dessa forma, todo método que o chama está ciente de que essa "exceção significativa" pode ocorrer nele.
Indique as exceções verificadas após os parâmetros do método após a throws
palavra-chave (não use a throw
palavra-chave por engano). Parece algo assim:
type method (parameters) throws exception
Exemplo:
exceção verificada | exceção não verificada |
---|---|
|
|
No exemplo à direita, nosso código gera uma exceção não verificada — nenhuma ação adicional é necessária. No exemplo à esquerda, o método lança uma exceção verificada , então a throws
palavra-chave é adicionada à assinatura do método junto com o tipo da exceção.
Se um método espera lançar várias exceções verificadas , todas elas devem ser especificadas após a throws
palavra-chave, separadas por vírgulas. A ordem não é importante. Exemplo:
public void calculate(int n) throws Exception, IOException
{
if (n == 0)
throw new Exception("n is null!");
if (n == 1)
throw new IOException("n is 1");
}
Requisito 2
Se você chamar um método que tenha verificado exceções em sua assinatura, não poderá ignorar o fato de que ele as lança.
Você deve capturar todas essas exceções adicionando catch
blocos para cada uma ou adicionando-as a uma throws
cláusula para seu método.
É como se estivéssemos dizendo: " Essas exceções são tão importantes que devemos capturá-las. E se não soubermos como tratá-las, qualquer pessoa que chamar nosso método deverá ser notificada de que tais exceções podem ocorrer nele.
Exemplo:
Imagine que estamos escrevendo um método para criar um mundo povoado por humanos. O número inicial de pessoas é passado como um argumento. Portanto, precisamos adicionar exceções se houver poucas pessoas.
Criando Terra | Observação |
---|---|
|
O método potencialmente lança duas exceções verificadas :
|
Essa chamada de método pode ser tratada de 3 maneiras:
1. Não pegue nenhuma exceção
Isso é feito com mais frequência quando o método não sabe como lidar adequadamente com a situação.
Código | Observação |
---|---|
|
O método de chamada não captura as exceções e deve informar os outros sobre elas: ele as adiciona à sua própria throws cláusula |
2. Pegue algumas das exceções
Nós lidamos com os erros que podemos lidar. Mas aqueles que não entendemos, jogamos para o método de chamada. Para fazer isso, precisamos adicionar seu nome à cláusula throws:
Código | Observação |
---|---|
|
O chamador captura apenas uma exceção verificadaLonelyWorldException — . A outra exceção deve ser adicionada à sua assinatura, indicando-a após a throws palavra-chave |
3. Capture todas as exceções
Se o método não lançar exceções para o método de chamada, o método de chamada sempre terá certeza de que tudo funcionou bem. E será incapaz de tomar qualquer ação para corrigir uma situação excepcional.
Código | Observação |
---|---|
|
Todas as exceções são capturadas neste método. O chamador terá certeza de que tudo correu bem. |
3. Capturando várias exceções
Programadores realmente odeiam duplicar código. Eles até criaram um princípio de desenvolvimento correspondente - DRY : Don't Repeat Yourself. Mas ao lidar com exceções, há ocasiões frequentes em que um try
bloco é seguido por vários catch
blocos com o mesmo código.
Ou pode haver 3 catch
blocos com o mesmo código e outros 2 catch
blocos com outro código idêntico. Esta é uma situação padrão quando seu projeto lida com exceções de forma responsável.
A partir da versão 7, a linguagem Java adicionou a capacidade de especificar vários tipos de exceções em um único catch
bloco. Parece mais ou menos assim:
try
{
// Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
// Exception handling code
}
Você pode ter quantos catch
blocos quiser. No entanto, um único catch
bloco não pode especificar exceções que herdam umas das outras. Em outras palavras, você não pode escrever catch ( Exception
| RuntimeException
e), porque a RuntimeException
classe herda Exception
.
GO TO FULL VERSION