Como criamos exceções personalizadas em Java?
Como criamos exceções personalizadas em Java?
Respostas:
Para definir uma exceção verificada, você cria uma subclasse (ou hierarquia de subclasses) de java.lang.Exception
. Por exemplo:
public class FooException extends Exception {
public FooException() { super(); }
public FooException(String message) { super(message); }
public FooException(String message, Throwable cause) { super(message, cause); }
public FooException(Throwable cause) { super(cause); }
}
Os métodos que podem potencialmente lançar ou propagar essa exceção devem declará-la:
public void calculate(int i) throws FooException, IOException;
... e o código que chama esse método deve manipular ou propagar essa exceção (ou ambas):
try {
int i = 5;
myObject.calculate(5);
} catch(FooException ex) {
// Print error and terminate application.
ex.printStackTrace();
System.exit(1);
} catch(IOException ex) {
// Rethrow as FooException.
throw new FooException(ex);
}
Você observará no exemplo acima que IOException
é capturado e mostrado novamente como FooException
. Essa é uma técnica comum usada para encapsular exceções (geralmente ao implementar uma API).
Às vezes, haverá situações em que você não deseja forçar todos os métodos a declarar sua implementação de exceção na cláusula throws. Nesse caso, você pode criar uma exceção desmarcada . Uma exceção desmarcada é qualquer exceção que se estende java.lang.RuntimeException
(que é uma subclasse de java.lang.Exception
):
public class FooRuntimeException extends RuntimeException {
...
}
Métodos podem lançar ou propagar FooRuntimeException
exceção sem declará-la; por exemplo
public void calculate(int i) {
if (i < 0) {
throw new FooRuntimeException("i < 0: " + i);
}
}
Exceções não verificadas geralmente são usadas para indicar um erro do programador, por exemplo, passando um argumento inválido para um método ou tentando violar os limites de um índice de matriz.
A java.lang.Throwable
classe é a raiz de todos os erros e exceções que podem ser lançados no Java. java.lang.Exception
e java.lang.Error
são as duas subclasses de Throwable
. Qualquer coisa que subclasse Throwable
possa ser lançada ou capturada. No entanto, geralmente é uma má prática capturar ou lançar, Error
pois isso é usado para indicar erros internos à JVM que geralmente não podem ser "manipulados" pelo programador (por exemplo OutOfMemoryError
). Da mesma forma, você deve evitar capturar Throwable
, o que pode resultar em capturar Error
s além de Exception
s.
Para uma exceção verificada:
public class MyCustomException extends Exception { }
Tecnicamente, qualquer coisa que se estenda Throwable
pode ser lançada, mas as exceções geralmente são extensões da Exception
classe, para que sejam verificadas exceções (exceto RuntimeException ou classes baseadas nela, que não são verificadas), em oposição ao outro tipo comum de lançamento, Error
s que geralmente não são algo projetado para ser manipulado normalmente além dos internos da JVM.
Você também pode tornar as exceções não públicas, mas só pode usá-las no pacote que as define, ao contrário dos pacotes.
No que diz respeito a lançar / capturar exceções personalizadas, ele funciona exatamente como as incorporadas -
throw new MyCustomException()
e pegar via
catch (MyCustomException e) { }
Throwable
pode ser lançada ; as exceções se estendem Exception
. Uma subclasse personalizada de Throwable não seria capturada por um try { ... } catch (Exception e) { ... }
bloco.
Error
não é uma exceção, é um erro). 3) Isso implica que qualquer subclasse de Exception seja verificada, enquanto RuntimeException não. A resposta dada por Adamski é muito mais precisa!