Definindo Exception(s)

Qualquer exceção é a instância de uma classe que tem a classe Throwable em sua hierarquia de herança. Ou seja, toda exceção é uma subclasse de java.lang.Throwable.

No instante em que uma exceção é lançada, o objeto de um subtipo de Throwable específico é instanciado e incluído no manipulador de exceções como um argumento para cláusula catch. Uma cláusula catch real tem o formato seguinte:

try{

//código

} catch (ArrayIndexOutOfBoundsException e){

e.printStackTarace();

}

Hierarquia de Exceções

As classes de exceções são subclasses de Throwable.

Existem dois subtipos que derivam de Throwable: Error e Exception. As classes que derivam de Error representam, situações excepcionais, que não são causadas por erros na programação e indicam algo que não ocorre normalmente na execução, como, por exemplo, a JVM ficar sem espaço na memória.

Manipulando uma hierarquia inteira de classes de exceções

Se a classe de execução que for especificada na cláusula catch não possui subclasses, então apenas a classe especificada será capturada. Porém, se a classe especificada na cláusula catch tiver subclasses, qualquer objeto de exceção com subclasses da classe especificada também será capturado.

Avalie o exemplo abaixo.

package br.com.devmedia;



public class X {



static void metodoX(){

String s = "Devmedia";

s.charAt(50);

}



static void metodoY(){

float f[]= new float[]{1.4F,4.5F};

f[7]=8.3F;

}



/**

* @param args

*/

public static void main(String[] args) {

try{

metodoX();

}catch (StringIndexOutOfBoundsException s) {

System.out.println("StringIndexOutOfBoundsException");

}

try{

metodoY();

}catch (ArrayIndexOutOfBoundsException e) {

System.out.println("ArrayIndexOutOfBoundsException");

}

}



}



Console:

StringIndexOutOfBoundsException

ArrayIndexOutOfBoundsException

Os manipuladores de exceção que capturarem diversas exceções de uma única vez possivelmente reproduzirão a confiabilidade do seu programa, uma vez que é bem possível que capturem uma exceção que não saibam tratar.

Os manipuladores de exceções mais específicos devem ser inseridos acima dos de exceções mais genéricas.

API e declarações de exceções

Do mesmo modo que um método precisa apontar que tipo e quantos argumentos aceitará, e o que será retornado, as exceções que um método pode lançar devem ser declaradas, a não ser que sejam subclasses de RuntimeException.

Apenas porque o método declara não quer dizer de fato que ele lançará tais exceções.

As exceções que não pertencerem a RuntimeException são consideradas verificadas (checked) porque o compilador fará uma checagem para ter plena certeza de que você sabe que algo inadequado pode ocorrer em determinado ponto.

Analise o código.

package br.com.devmedia;



import java.sql.SQLException;



public class Teste {



static void conect ()throws SQLException{}

static void conectCatch(){

try{

conect();

}catch (SQLException e) {

e.printStackTrace();

}

}



/**

* @param args

*/

public static void main(String[] args) {

conectCatch();

}



}

Durante a prova procure por códigos que chamem um método para declarar uma exceção, na qual o método que estiver chamando não trate ou declare a exceção verificada.

Lançando uma Exception

Mesmo na situação de um método declarar uma exceção RuntimeException, o método que o invocar não será obrigado a manipulá-la ou declará-la. As exceções Error, e RuntimeException todos os seus subtipos são exceções não verificadas que não precisam ser apontadas ou manipuladas.

É necessário saber a diferença entre um objeto Error e exceções verificadas e não verificadas. Objetos do tipo Error não são objetos Exception, mesmo que representem condições excepcionais.

Tanto Error quanto Exception compartilham uma superclasse em comum, Throwable; sendo assim, os 2 objetos podem ser lançados com o uso da palavra-chave throw.

No momento em que um objeto Error, ou uma subclasse de Error, é lançado, ele não é verificado. Não é necessário capturar objetos Error.

Observe o código abaixo, que explana o que abordamos.

package br.com.devmedia;



public class X {



static void metodo1(){

metodo2();

}



static void metodo2(){

metodo1();

}



/**

* @param args

*/

public static void main(String[] args) {

metodo1();

metodo2();

}



}

Seu programa já estaria danificado no instante em que se capturasse o erro. Então, não existe realmente por que capturar um desses tipos de erro. Somente lembre-se de que você pode fazê-lo. O exemplo a seguir compila corretamente.

package br.com.devmedia;



public class ErrorTest {



static void doSomething(){

try{

throw new Error();

}catch (Error e) {

throw e;

}

}



static void metodoB(){

doSomething ();

}



}

Se for lançada uma exceção verificada a partir de um catch, também que ser declarado essa exceção. Ou seja, terá que manipular e declarar ou terá que não manipular e declarar. Analise o exemplo contendo duas classes e a saída no console correspondente.

package br.com.devmedia;



public class TestException {



/**

* @param args

*/

public static void main(String[] args) {

ExcecaoException a = new ExcecaoException();

try {

a.verificaNumber(16);

a.verificaNumber(9);

} catch (ExcecaoException e) {

System.out.println("Número inferior ao mínimo.");

}





}



}

class ExcecaoException extends Exception{

void verificaNumber(int numero) throws Excecao1Exception{

if(numero < 15){

throw new ExcecaoException();

}else{

System.out.println("Número aceito");

}

}

}



Console:

Número aceito

Número inferior ao mínimo.

Na continução abordaremos as Assertivas.


Leia todos artigos da série