Como criar exceções personalizadas em Java?

Como criamos exceções personalizadas em Java?

Para definir uma exceção verificada, você cria uma subclass (ou hierarquia de subclasss) 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); } } 

Métodos que podem potencialmente lançar ou propagar essa exceção devem declará-lo:

 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 ambos):

 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ê notará no exemplo acima que IOException é capturado e relançado 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 quer forçar todos os methods a declarar sua implementação de exceção em sua cláusula throws. Nesse caso, você pode criar uma exceção não verificada . Uma exceção não verificada é qualquer exceção que estenda java.lang.RuntimeException (que em si é uma subclass de java.lang.Exception ):

 public class FooRuntimeException extends RuntimeException { ... } 

Os methods podem lançar ou propagar a exceção FooRuntimeException sem declará-la; por exemplo

 public void calculate(int i) { if (i < 0) { throw new FooRuntimeException("i < 0: " + i); } } 

As exceções não verificadas são normalmente usadas para denotar 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 class java.lang.Throwable é a raiz de todos os erros e exceções que podem ser lançados dentro de Java. java.lang.Exception e java.lang.Error são ambas subclasss de Throwable . Qualquer coisa que a subclass Throwable possa ser lançada ou capturada. No entanto, normalmente é uma má prática capturar ou lançar Error pois isso é usado para denotar erros internos da JVM que normalmente não podem ser "manipulados" pelo programador (por exemplo, OutOfMemoryError ). Da mesma forma, você deve evitar capturar Throwable , o que poderia resultar na captura de Error s além de Exception s.

 public class MyException extends Exception { // special exception code goes here } 

Jogue como:

  throw new MyException ("Something happened") 

Pegar como:

 catch (MyException e) { // something } 

Para uma exceção verificada:

 public class MyCustomException extends Exception { } 

Tecnicamente, qualquer coisa que estenda Throwable pode ser lançada, mas as exceções geralmente são extensões da class Exception para que sejam exceções verificadas (exceto RuntimeException ou classs baseadas nele, que não são verificadas), ao contrário do outro tipo comum de Throwable. throwable, Error s, que geralmente não são algo projetado para ser manipulado de forma agradável 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 os internos – jogue via

 throw new MyCustomException() 

e pegar via

 catch (MyCustomException e) { }