Exceptions em Java Exceptions em Java Leonardo Freitas 21-7819-2047 e 21-9653-4620 [email protected] [email protected] Exceptions em Java Reflexão "A mente que se abre a uma nova idéia jamais voltará ao seu tamanho original." Albert Einstein - A vida é um eterno aprendizado - Ninguém é o dono da verdade - Seja crítico - Nunca desista Exceptions em Java Exceptions em Java - Agenda •Introdução •Vantagens da manipulação de exceções •A estrutura try catch finally •Definindo melhor exceções •Hierarquia de exceções •Manipulando uma hierarquia inteira de exceções •Correspondência de exceções •Declaração de exceções e a interface pública •Por que objetos do tipo error não são simplesmente do tipo exception •Relançando a mesma exceção •De onde vêm as exceções •Exceções lançadas pela JVM •Exceções lançadas programaticamente •Resumão de BOAS PRÁTICAS Exceptions em Java Introdução • Um velho axioma relacionado ao desenvolvimento de softwares diz que 80% do trabalho (esforço necessário para identificar e manipular erros) são usados em 20% do tempo • Na programação estruturada, desenvolver programas que lidam com erros é monótono e transforma o código-fonte do aplicativo em um emaranhado confuso. • Na programação orientada a objetos, aqui especificamente na Linguagem Java, existe um mecanismo sofisticado para manipulação de erros que produz códigos de manipulação eficientes e organizados: a manipulação de exceções. Exceptions em Java Introdução •Definição simples de exceção: condição excepcional que altera o fluxo normal do programa •Algumas causas: falhas de hardware, exaustão de recursos e erros diversos • Nomenclatura: quando um evento excepcional ocorre em Java, diz-se que uma exceção será lançada. O código que é responsável por fazer algo com a exceção é chamado de manipulador de exceções, que captura a exceção lançada. Exceptions em Java Vantagens da manipulação de exceções •Fácil detecção de erros sem a escrita de um código especial para testar valores retornados; • Permite manter um código de manipulação de exceções nitidamente separado do código que gerará a exceção • Permite que o mesmo código de manipulação de exceções lide com as diferentes exceções possíveis. Exceptions em Java As estrutura try catch finally A palavra chave try indica um bloco de código no qual possam ocorrer exceções (região protegida); Uma ou mais cláusulas catch associarão uma exceção específica (ou classe de) a um bloco de código que a manipulará finally é o bloco apropriado para a limpeza depois da execução do código no bloco try (por exemplo, para fechar um arquivo ou liberar um socket*) * Especificamente em computação, um soquete pode ser usado em ligações de redes de computadores para um fim de um elo bidirecional de comunicação entre dois processos. A interface padronizada de soquetes surgiu originalmente no sistema operacional Unix BSD (Berkeley Software Distribution); portanto, eles são muitas vezes chamados de Berkeley Sockets. É também uma abstração computacional que mapeia diretamente a uma porta de transporte (TCP ou UDP) e mais um endereço de rede. Com esse conceito é possível identificar unicamente um aplicativo ou servidor na rede de comunicação IP. Exceptions em Java Exemplo de try catch Exceptions em Java Exemplo de try catch Exceptions em Java Exemplo de try catch finally Exceptions em Java Exemplo de try catch finally Exceptions em Java Exemplo prático de try catch finally (sem tratamento) Output Exceptions em Java Exemplo prático de try catch finally (revisado) Output Exceptions em Java Definindo melhor exceções • Em Java, tudo que não for um tipo primitivo deve ser um objeto (inclusive as exceções) • Toda exceção é a instância de uma classe que possui a classe Exception em sua hierarquia de herança. Em outras palavras, as exceções são sempre alguma subclasse de java.lang.Exception Exceptions em Java • Exemplo de exceção: • Neste exemplo, e é a instância de uma classe chamada resumidamente de ArrayIndexOutOfBoundsException. Como ocorreria com qualquer outro objeto, seus métodos podem ser chamados. Exceptions em Java Hierarquia de exceções • Error: situações incomuns que não são causadas por erros no programa e indicam eventos que não ocorreriam normalmente durante sua execução (exemplo: a JVM ficar sem espaço na memória). Geralmente os aplicativos não conseguem se recuperar de um erro, portanto não precisamos manipulá-los. • Erros tecnicamente não são exceções, pois não derivam da classe exception Exceptions em Java Hierarquia de exceções • A classe throwable fornece aos seus descendentes alguns métodos úteis em manipuladores de exceções. • O método printStackTrace(), por exemplo, exibe o rastreamento de pilha do local onde a execução ocorreu, através do processo chamado de desenrolamento de pilha. Exceptions em Java Manipulando uma hierarquia inteira de exceções • Se a classe especificada na cláusula catch tiver subclasses, qualquer objeto de exceção com subclasses da classe especificada também será capturado • Exemplo: IndexOutOfBoundsException • ArrayIndexOutOfBoundsException • StringIndexOutOfBoundsException Exceptions em Java Correspondência de exceções • Propagação top-down na pilha de camadas. • Exemplo: • Não funciona, pois há possíveis exceções derivadas de IOException que não foram tratadas (por exemplo EOFException) Exceptions em Java • Agora sim, IOException abrange todas as exceções que podem ocorrer na região protegida: Exceptions em Java Correspondência de exceções • Manipuladores de exceções mais específicos devem sempre ser inseridos acima dos de exceções gerais • Para exceções que sejam irmãs na hierarquia de classes, a ordem não importa Exceptions em Java Correspondência de exceções • Exemplo prático: • Compila? • Compila? Exceptions em Java Correspondência de exceções • Exemplo prático: • Compila! • Não Compila! Exceptions em Java Declaração de exceções e a interface pública • Assim como um método precisa especificar 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 menos que sejam subclasses de RuntimeException) RuntimeException hierarchy Exceptions em Java Declaração de exceções e a interface pública Exceptions hierarchy Exceptions em Java Declaração de exceções e a interface pública •A palavra-chave throws é usada da forma descrita a seguir para listar as exceções que um método pode lançar: Exceptions em Java Declaração de exceções e a interface pública • Observações bem importantes: • Só por que o método declara que lança uma exceção não significa que sempre o fará. Ele apenas informa que pode fazê-lo • Se você declarar a exceção que seu método capturará de outro método e não fornecer um bloco try/catch para ele, então o método propagará a exceção de volta para o método que o chamou e ela será capturada ou continuará a ser transferida através do fluxo, para ser manipulada por um método mais abaixo na pilha • Qualquer método que puder lançar uma exceção, inclusive os métodos que estiverem apenas transferindo uma exceção para o próximo método da pilha, também devem declará-la (a menos que ela seja uma subclasse de RuntimeException) • O compilador não verifica declarações de classes derivadas de RuntimeException Exceptions em Java Declaração de exceções e a interface pública • Requisito “Tratar ou declarar” (ou “Capturar ou declarar”): •“Todo método deve ou tratar todas as exceções verificadas, fornecendo uma cláusula catch, ou então listar cada exceção verificada que não tiver recebido tratamento como uma exceção lançada” Exceptions em Java Declaração de exceções e a interface pública • Exemplo: •Problema: O método doMore() lança uma exceção verificada, mas não a declara! • Se declararmos o método doStuff() ainda apresentará problemas, porque ele também precisa declarar a exceção IOException, a menos que a manipule por meio do fornecimento de um bloco try/catch, com uma cláusula catch que possa tratar a exceção IOException Exceptions em Java Declaração de exceções e a interface pública • Voltando às exceções RuntimeException: • Como vimos, um objeto do tipo RuntimeException pode ser lançado de qualquer método sem ser especificado como parte da interface pública do método (e sem a necessidade de um manipulador) • Mesmo se um método declarar realmente uma exceção RuntimeException, o método que o chamar não será obrigado a manipulá-la ou declará-la (pois ela faz parte das unchecked exceptions) Exceptions em Java Declaração de exceções e a interface pública • As exceções RuntimeException, Error e todos os seus subtipos são unchecked exceptions e as unchecked exceptions não precisam ser especificadas ou manipuladas. Exceptions em Java Declaração de exceções e a interface pública • Vejamos uma checked exception na prática: • Vamos examinar myMethod1(). Já que a exceção EOFException é subclasse de IOException, que, por sua vez, é subclasse de Exception, ela será verificada e deve ser declarada como uma exceção que pode ser lançada por esse método. • Agora, de onde realmente virá a exceção? A interface pública do myMethod2() declara que uma exceção desse tipo pode ser lançada. Se ele realmente lançará a exceção ou chamará um outro método para lançá-la, não tem importância. Apenas sabemos que temos de capturar a exceção ou declarar que a lançamos. • O método myMethod1() portanto não captura a exceção, ele declara que a lançará. Exceptions em Java Declaração de exceções e a interface pública • Atenção: Um códigos com um método que lance uma checked exception sem capturá-la em algum local não compila!! Exceptions em Java Declaração de exceções e a interface pública • Agora uma unchecked exception: • NullPointerException é derivada de RuntimeException, logo é unchecked e não precisará ser declarada (como no caso). Exceptions em Java Porque objetos do tipo error não são simplesmente do tipo exception •Objetos do tipo error não são objetos exception, embora representem condições excepcionais • Apesar de possível, não é comum lançar/capturar objetos do tipo error (como é feito com objetos do tipo exception), pois são exceções da máquina, não do código de programação • Exemplos: •Ao receber um objeto OutOfMemoryError a JVM já lutara desesperadamente para tratá-lo, logo não há o que fazer. •Ao receber um objeto VirtualMachineError o programa já estaria danificado. Exceptions em Java Relançando a mesma exceção • É possível lançar a mesma exceção de acabou de ser capturada em uma cláusula catch • Exemplo: • Nesse caso, todas as outras cláusulas catch associadas ao mesmo bloco try serão ignoradas, um bloco finally, se existir, será executado e a exceção será lançada novamente para o método chamador (o próximo método na pilha de camadas) • Atenção: se você lançar uma checked exception a partir de uma cláusula catch, também terá que declarar essa exceção!!! (Ou seja, terá que manipular e declarar, não manipular ou declarar) Exceptions em Java Relançando a mesma exceção • Este exemplo não é válido: • Como a exceção foi lançada a partir de uma cláusula catch, é preciso declarar o IOException!! Exceptions em Java De onde vêm as exceções • Exceções lançadas pela JVM: As exceções ou erros que são ou exclusivos ou mais logicamente lançados pela JVM • Exceções programáticas: As exceções lançadas explicitamente pelo aplicativo e/ou pelos programadores da API Exceptions em Java Exceções lançadas pela JVM • Exemplo: NullPointerException • Neste caso, o programa tenta acessar um objeto usando uma variável de referência com um valor atual null. O compilador não encontra problemas desse tipo antes do tempo de execução. Exceptions em Java Exceções lançadas pela JVM • Exemplo: StackOverflowException • Iniciando a pilha de camadas, main chamará o go(), que chamará go(), que chamará go()… não há SO que agüente!!! (Nem o Chuck Norris SO…) Exceptions em Java Exceções lançadas programaticamente • Relembrando: algo criado por um aplicativo e/ou por um desenvolvedor de API • Há muito tempo, algum programador escreveu a classe java.lang.Integer (classe Wrapper) e criou métodos como parseInt() e valueOf(). Esse programador decidiu sabiamente que, se um desses métodos recebesse uma String que não pudesse ser convertida em um número, o método deveria lançar uma NumberFormatException. • O código parcialmente implementado poderia se parecer com o seguinte: Exceptions em Java Exceções lançadas programaticamente •O desenvolvedor poderia ter usado IllegalArgumentException (lançada quando um método recebe um argumento formatado de forma diferente da que o método espera) para o método parseInt() • Porém, quando há uma hierarquia de exceções, deve-se usar a exceção mais precisa que puder (no caso NumberFormatException extende IllegalArgumentException) • Quando criamos nossas próprias exceções podemos considerá-las como exceções lançadas programaticamente Exceptions em Java Resumão de BOAS PRÁTICAS • try/catch/finally = Use quando a classe for responsável por tratar o dito erro. Se o erro pode ser tratado mais para frente de uma maneira mais comum ao projeto, não utilize. • throws = Use quando o erro não for de responsabilidade da classe. Ela simplesmente será executada e lançará qualquer erro para ser mais adequadamente tratado em uma classe própria para isso. • Exemplo: Acessar de várias maneiras um servidor (seja via sockets ou um post ao servlet). Se uma maneira falha, a exception é jogada para frente, a classe tenta da outra maneira e trabalha com o erro gerado. Exceptions em Java P E R G U N T A S R E S P O S T A S // Até a próxima!!!!!!!