Tratamento de exceçãoO tratamento de exceção, na ciência da computação, é o mecanismo responsável pelo tratamento da ocorrência de condições que alteram o fluxo normal da execução de programas de computadores. Para condições consideradas parte do fluxo normal de execução, ver os conceitos de sinal e evento. Em geral, na ocorrência de uma exceção, o estado do programa é gravado em um local pré-definido e a sua execução é direcionada para uma rotina de tratamento. Dependendo da situação, a rotina de tratamento pode prosseguir a execução a partir do ponto que originou a exceção, utilizando a informação gravada para restaurar o estado. Um exemplo de exceção que normalmente permite o prosseguimento da execução é aquela originada de uma falta de página (page fault). Por outro lado, uma . Do ponto de vista do processador, as interrupções de hardware podem ser consideradas como condições análogas às exceções que permitem prosseguimento da execução, apesar destas exceções não serem normalmente relacionadas com o fluxo normal do programa. Para o desenvolvedor de uma rotina, lançar uma exceção é um modo útil de assinalar que a rotina não deve continuar a execução quando, por exemplo, os argumentos de entrada não são válidos (um denominador igual a zero em uma divisão, por exemplo) ou quando um recurso no qual o programa depende não está disponível (um arquivo não encontrado ou um erro em um disco, por exemplo). Em sistemas que não utilizam o conceito de exceções as rotinas devem retornar algum código de erro especial. Porém esta abordagem é muitas vezes difícil de implementar devido ao problema do predicado, onde os usuários da rotina precisam escrever código extra para distinguir os valores de retorno normais daqueles que indicam erro. Aplicações segurasUma porção de código é considerada "segura", no contexto do tratamento de exceções, se as falhas no código, ocorridas em tempo de execução, não produzem efeitos prejudiciais, como vazamentos de memória, corrupção de dados ou saída inválida. Um código seguro deve satisfazer invariantes mesmo após a ocorrência de exceções. Os níveis de segurança relacionados ao tratamento de exceção podem ser colocados da seguinte forma:
Normalmente um nível básico de segurança é requerido. A transparência à falhas é difícil de implementar e normalmente não é possível de atingir em bibliotecas onde o conhecimento completo da aplicação não está disponível. Suporte a tratamento de exceções em linguagens de programaçãoMuitas linguagens de programação, como Ada, Object Pascal, C++, D, Delphi, Eiffel, Java, Objective-C, OCaml, PHP (versão 5), Python, REALbasic, ML, Ruby, e todas linguagens do framework .NET contém suporte nativo para tratamento de exceção. Nestas linguagens, no advento de uma exceção (mais precisamente, uma exceção tratada pela linguagem), a pilha de execução é varrida até que uma rotina de tratamento de exceção seja encontrada. Isto é, se a função , que contém uma rotina de tratamento para a exceção , chama a função , que por sua vez chama a função , e a exceção ocorre em , então a função e irão terminar em se tratar . Existem apenas alguns poucos estilos de tratamento de exceção em uso, que contém pequenas diferenças entre si. No estilo mais popular, uma exceção é iniciada por uma declaração especial ( Algumas poucas linguagens também permitem o uso da cláusula ( Linguagens com tratamentos de exceções:
Linguagens que não oferecem mecanismos de tratamento de exceções:
O código de tratamento de exceções pode parecer como o mostrado abaixo (em pseudo-código): try { line = console.readLine(); if (line.length() == 0) { throw new EmptyLineException("A linha lida da console está vazia!"); } console.printLine("Alô %s!" % line); } catch (EmptyLineException e) { console.printLine("Alô!"); } catch (Exception e) { console.printLine("Erro: " + e.message()); } else { console.printLine("O programa executou com sucesso."); } finally { console.printLine("O programa termina neste momento."); } Algumas linguagens utilizam uma única cláusula de tratamento, que trata internamente a classe da exceção. As linguagens Perl e C não usam o termo "tratamento de exceção", mas incluem facilidades que permitem a implementação de uma funcionalidade similar. Exceções verificadasOs projetistas da linguagem Java desenvolveram um conjunto especial de exceções[2][3][4]: as exceções verificadas (checked exceptions).[5] As exceções verificadas que um método pode lançar devem fazer parte da sua assinatura. Por exemplo, se um método pode lançar a exceção Este mecanismo é relacionado com os verificadores de exceção que existem no OCaml (uma implementação da linguagem Caml). A ferramenta externa para o OCaml é transparente (não requer qualquer anotação sintática) e facultativa (é possível compilar e executar uma aplicação sem verificar as exceções, apesar disto não ser recomendável para código utilizado em produção). A linguagem de programação CLU possui uma funcionalidade com interface próxima ao que foi introduzido posteriormente pela linguagem Java. Uma função pode lançar apenas as exceções listadas no seu tipo, mas qualquer exceção não listada, lançada quando da chamada de uma função, pode ser automaticamente transformada em uma exceção de tempo de execução (runtime), ou falha, ao invés de resultar em um erro em tempo de compilação. Mais tarde, a linguagem Modula-3 incorporou uma funcionalidade similar.[6] Estas funcionalidades não incluem a verificação em tempo de compilação, que é central ao conceito de exceções verificadas e que, até o ano de 2006, não haviam sido incorporadas nas principais linguagens de programação, com exceção da linguagem Java.[7] Prós e contrasAs exceções verificadas podem, em tempo de compilação, reduzir consideravelmente (mas não eliminar inteiramente) a ocorrência de casos em que de exceções não tratadas emergem para fora da aplicação; as exceções não verificadas ( Porém, alguns criticam as exceções verificadas alegando que esta sintaxe requer assinaturas de métodos com extensas declarações de cláusula Outros consideram que os problemas citados podem ser resolvidos se o número de exceções declaradas for reduzida através da utilização de uma superclasse que generalize todas as classes de exceções potencialmente lançadas ou pela definição e declaração de tipos de exceção adequadas para o nível de abstração correspondente ao método chamado[9] através do mapeamento de exceções de nível mais baixo a estes tipos, preferencialmente envolvendo estas exceções através do uso do mecanismo de encadeamento de exceções com o objetivo de preservar a exceção raiz. Um simples declaração Uma visão predominante considera que as exceções não verificadas não devem ser tratadas, com exceção do nível mais externo do escopo do programa, pois elas frequentemente representam cenários em que a recuperação não é possível: as exceções de Sincronicidade de exceçõesA sincronicidade de exceções é relacionada de certa forma com o conceito das exceções verificadas. As exceções síncronas ocorrem em declarações específicas de um programa enquanto que exceções assíncronas podem ser lançadas em praticamente qualquer lugar.[10][11] Além disso o tratamento das exceções assíncronas não pode ser requerido pelo compilador e o seu tratamento é difícil de programar. Como exemplos de exceções naturalmente assíncronas pode-se citar o evento decorrente do ato de pressionar as teclas Ctrl-C com o intuito de interromper um programa. Tipicamente, as linguagens lidam com este problema limitando a "assincronicidade". Por exemplo, a linguagem Java perdeu as características que permitiam a parada e reinicialização da execução de threads perdidas, para evitar que objetos fiquem em um estado inconsistente.[12] Sistemas baseados em condiçõesAs linguagens Common Lisp, Dylan e Smalltalk possuem um sistema de condições que englobam as funcionalidades dos sistemas de tratamento de exceções. Nestas linguagens ou ambientes o advento de uma condição ("a generalização de um erro" segundo Kent Pitman) implica uma chamada de função, e somente no escopo da subrotina de tratamento de exceção a decisão de varrer a pilha de execução é tomada. As condições podem ser entendidas como a generalização das exceções. Quando uma condição surge, uma subrotina apropriada de tratamento de condições é procurada e selecionada, na ordem da pilha, para tratar a condição. As condições que não representam erros podem ser ignoradas com segurança; o seu único propósito pode ser a propagação de alertas para o usuário.[13] Exceções "continuáveis"As exceções "continuáveis" são relacionadas com o modelo conhecido como "modelo do recomeço" de tratamento de exceções, na qual algumas exceções são ditas como "continuáveis"; permitem que a execução retorne ao ponto que originou a exceção, após a subrotina de tratamento de exceções ter tomado as ações corretivas necessárias. O sistema de condições é generalizado da seguinte forma: dentro da subrotina de tratamento de condições consideradas não sérias (exceções "continuáveis" ou, em inglês, continuable exception), é possível saltar para pontos de reinicio pré-definidos (restarts) que residem entre a expressão que sinalizou a exceção e a subrotina de tratamento da condição. Referências
Ligações externas
Information related to Tratamento de exceção |