Permite separar as partes que devem executar normalmente
daquelas que devem ser executadas apenas em caso de problemas
Vantagens
- Legibilidade
- Confiabilidade
- Encapsulamento
- Reuso
No caso de problemas
- Subprograma lança uma exceção
Tratamento pode ser feito em diferentes níveis
Mecanismo oferecido pela linguagem (mais recente)
um STE deve ser capaz de (ou permitir)
- Detectar a ocorrência de uma situação anormal
- Identificar o tipo do problema, e Disparar a exceção apropriada
- Capturar a exceção em algum ponto do programa
- Ter código de tratamento para Tratar a exceção
- Como e onde os tratadores de exceção são especificados?
- Qual seu escopo?
- Como a ocorrência de uma exceção é vinculada a um tratador?
- Onde a execução continua após o tratamento da exceção?
- Há exceções pré-definidas?
- Exceções pré-definidas podem ser ativadas explicitamente?
- Deve existir tratadores padrão?
- Erros detectáveis por hardware são tratados como exceções que podem ser manipuladas?
- Deve ser possível desativar exceções?
Pré-definidas (embutidas na linguagem)
Definidas pelo programador, podendo ser
- Totalmente livres (ML)
- Criadas com base em exceções existentes \ (Java, Objective-C, C++, …)
Tratáveis
- Código de tratamento pode ser elaborado
- Programa pode compensar o erro e seguir em frente
Não-tratáveis
- Compensação de erro impossível
- Execução é terminada
Exemplo da linguagem Java (ver documentação de Throwable
)
Parametrizáveis
- A exceção pode carregar parâmetros ao código de tratamento
- Em linguagem OO, exceções são implementadas como classes
Não-Parametrizáveis
- Sem parâmetros
Verificadas (checked)
- Programador deve fornecer código de tratamento
Não-verificadas (unchecked)
- Não há necessidade de tratamento
Exemplo da linguagem Java (documentação de Throwable
)
- Procurar pour
checked
Implicitamente
- Lançadas pelo ambiente operacional
- Todas as pré-definidas
- Divisão por zero
- Overflow
- Erros de subscritos
- Acesso a conteúdo de ponteiro nulo
Explicitamente
- Lançadas pelo próprio programa
- Normalmente protegidas por uma condição
if condicao throw minha_excecao
Exemplos de lançamento explícito
if (t==NULL) throw new NullPointerException(); //Java
if t<l raise RunTimeError('valor invalido');//Python
if n<0 then raise ValorInvalido; //ML
STE oferece um jeito de especificar regiões monitoradas
Comando try
em Java/C++
try {
...
}
Comando try
em Python
try:
arq = open("arq", "w")
arq.write("teste")
STE oferece um jeito de especificar blocos de tratamento
- Capturam tipos específicos (declarados) de exceção
Comando catch
em Java/C++
catch (NumberFormatException e){
System.out.println ("Entrada Invalida");
}
Comando except
em Python
except IOError:
print "Erro: arquivo não encontrado"
Comando handle
em ML
checked_fatorial n handle fatorial
=> print "n invalido"
Compensação do erro
- Recuperar um estado válido
- Continuar a execução normal
Se a recuperação não é possível
- Imprimir uma mensagem de erro significativa
- Terminar o programa graciosamente
Se a exceção não pode ser tratada no bloco
- Liberar recursos alocados localmente
- Propagar a exceção para o bloco chamador
Tratar exceções gera um fluxo de controle alternativo
- Fluxo excepcional
Exemplo de fluxo de execução normal
//A
try {
//B
num = Integer.parseInt(stdin.readLine());
valido = true;
}catch (NumberFormatException exc) {
//C
System.out.println(“Entrada invalida.”);
}catch (IOException exc) {
//D
System.out.println(“Problema de E/S. Terminando!”);
System.exit(0);
}
//E
Tratamento local no mesmo subprograma (com try-catch
)
Propagação → tratamento em outro ponto do programa
Em java, as exceções verificadas devem ser tratadas localmente
- O compilador
javac
garante que o método deve tratá-lo - Se não tratadas, devem aparecer no cabeçalho (com
throws
) - Exemplo ./Teste.java
Propagação acontece através do encadeamento dinâmico
Registrado em cada registro de ativação na pilha
Para cada subprograma (RA) empilhado que não é tratador
- RA correspondente é desempilhado
- Objetos criados são destruídos
No momento que a exceção é tratada
- Bloco imediatamente posterior ao do tratador é executado
Se nenhum tratador é encontrado
- Exceção chega ao método principal, que termina o programa
- Exemplo:
Teste.java
Para cada subprograma (RA) empilhado que não é tratador
- RA correspondente é desempilhado
- Objetos criados são destruídos
C++
- Exceção sai do escopo ⇒ Chamada de métodos destrutores
- Totalmente implícito e automático
Java e Python
- Programador deve escrever o bloco
finally
Bloco sempre executado, independente se houve exceção
Java: finally
try { ... }
catch (Tipo1 e1) { ... }
catch (Tipo1 e1) { ... }
finally { ... }
Python: finally/else
try:
except Tipo1:
except Tipo2:
finally:
#sempre executado
else:
#executado se não houver exceção