Definindo Exceções em Java: Desmistificando a Certificação SCJP6 Parte IX - Parte 2

Nesta parte do artigo trataremos um pouco mais de Exception, suas definições e sua API.

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

Artigos relacionados