Excepciones Excepciones Excepciones Excepciones

Anuncio
Excepciones
Excepciones
Condiciones inesperadas en un programa
Pueden ocurrir al llamar métodos de objetos
Programación Orientada a Objetos
Facultad de Informática
Ejemplos
Juan Pavón Mestras
Dep. Ingeniería del Software e Inteligencia Artificial
Universidad Complutense Madrid
Se pueden tratar en el nivel donde ocurren (quien invoca el
método)
O en un nivel superior de la pila de llamadas
Abrir un fichero que no existe
Intentar invocar un método en un objeto que no existe
(referencia null)
Utilizar un array fuera de su rango
Se cae una conexión de red que se estaba utilizando
Inconsistencia del estado del objeto
Falta una información para realizar una operación
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
if ( función(parámetros) == UN_ERROR ) {
// tratar error
}
else {
// código normal
}
En el código de los métodos se puede indicar la ocurrencia de
la excepción y esto ocasiona la finalización inmediata del
método
• Por ejemplo el incumplimiento de alguna condición necesaria
para la ejecución del método
• También pueden ocurrir excepciones del entorno (no originadas
explícitamente por la aplicación)
• Síncronas: división por cero, acceso fuera de los límites de un array,
puntero nulo
• Asíncronas: algún fallo del sistema, caída de comunicaciones, falta de
memoria
El código del llamante se puede estructurar en dos partes:
• Secuencia normal de ejecución
• Tratamiento de excepciones: qué hacer cuando se sale del flujo
normal de ejecución por la ocurrencia de alguna excepción
• Por ejemplo, en C++ al quedarse sin memoria al hacer new o
cuando se cae una conexión
Excepciones
En lenguajes de POO modernos se estructura el
tratamiento de excepciones:
Mecanismo simple
Pero complica el código (cuando hay varias funciones
empiezan a anidarse los if-else)
Hay errores de ejecución que no pueden capturarse
fácilmente
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
2
Excepciones
Tradicionalmente esto se hace devolviendo un valor la
función llamada que indica si todo ha ido bien o no
Excepciones
3
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
4
Excepciones en Java
Las excepciones son objetos
Excepciones en Java
De la clase Exception, que hereda de Throwable
Comprobadas,
el compilador obliga
a considerarla
En Java puede haber dos tipos de excepciones:
Excepciones que no requieren comprobarse
• Errores y excepciones de ejecución
• Clase RuntimeException
Throwable
Error
Exception
Excepciones que hay que comprobar
• Todas las demás
• Heredan de la clase Exception
ExcepciónUsuario RuntimeException
Cuando ocurre una excepción se dice que se lanza (throw)
throw new Excepción();
Sin comprobación,
las lanza la MVJ
La excepción puede ser capturada para tratarla (catch)
catch (Excepción e) { tratamiento(); }
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
5
Excepciones en Java
Son las que puede lanzar la MVJ
• Normalmente representan una condición fatal del programa
• No las comprueba el compilador y es difícil saber cuándo y por
qué pueden suceder
NullPointerException
ArrayIndexOutOfBoundsException
• Cuando se envía un mensaje a un objeto null
• Cuando se accede a un índice ilegal en un array
• Pero a veces se puede considerar que alguna condición podría
ocasionarlas
• Se suelen tratar en algún nivel superior de forma genérica
Comprobadas:
Excepciones con comprobación
• Si no se consideran en el código, el compilador indica un error
• Estas excepciones son lanzadas por métodos que se usan en el
código (por eso las reconoce el compilador)
• El programador tiene que definir lo que hacer cuando ocurran
Excepciones
IOException
• Clase genérica para las excepciones que se producen en
operaciones de E/S
Las comprueba el compilador
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
6
No comprobadas, subclases de RuntimeException:
• Ocurren en tiempo de ejecución
Excepciones
Algunas excepciones comunes en Java
Excepciones sin comprobación obligatoria
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
NoSuchMethodException
ClassNotFoundException
• Cuando no se encuentra un método
• Cuando una aplicación intenta cargar una clase pero no se
encuentra su definición (el fichero .class correspondiente)
7
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
8
Algunos errores comunes en Java
Gestión de excepciones
NoSuchMethodError
La aplicación llama a un método que ya no existe en la
definición de la clase
NoClassDefFoundError
Cómo se haga depende del diseño general del sistema
La MVJ intenta cargar una clase pero no se encuentra
• Suele ocurrir si el CLASSPATH no está bien o si la clase (.class)
no está donde se espera
ClassFormatError
La MVJ intenta cargar una clase desde un fichero incorrecto
9
Excepciones
Se pueden capturar múltiples excepciones
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
10
Bloque finally
El orden de captura de las excepciones es importante
Se manejan en un bloque try-catch (si no, se propagan
hacia el llamante):
public void unMétodo(){
try{
//código donde se puede lanzar la excepción e
}catch(Exception e){
//código que gestiona la exception e
}
}
• Suele ocurrir cuando el fichero .class está corrupto, o si no es un
fichero .class
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Tratarla en el método que las captura
Propagarla al método llamante
• Si al final nadie captura la excepción, el programa acaba y se
lista la traza de la pila de llamadas
• Sólo puede ocurrir si la clase cambia su definición en tiempo de
ejecución
Hay dos mecanismos para gestionar una excepción:
Las más genéricas se deberían capturar al final
Se ejecuta siempre al final, después del último bloque catch
Generalmente se utiliza para hacer limpieza
• Cerrar ficheros, conexiones, etc.
public void unMétodo(){
try{
// código donde se puede lanzar la excepción e1
// código donde se puede lanzar la excepción e2
}catch(MiExcepción e1){
// código que gestiona la exception e1
Exception
}catch(Exception e2){
// código que gestiona la exception e2
}
}
public void miMétodo(){
try{
// código donde se puede lanzar la excepción e1
// código donde se puede lanzar la excepción e2
} catch(MiExcepción e1){
// código que gestiona la exception e1
} catch(Exception e2){
// código que gestiona la exception e2
} finally{
//código de limpieza, liberar recursos (close)
}
}
MiExcepción
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
11
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
12
Propagación de excepciones
Gestión genérica de excepciones
Es la segunda estrategia, en vez del bloque try-catch
Deja que sea el método llamante quien gestione la excepción
Hay que declarar que el método puede lanzar la excepción
Se puede capturar una excepción genérica para capturar
todas las que sean de ese tipo y subtipos
Por ejemplo, capturando Exception se pueden capturar todas
las excepciones posibles
Y capturando Throwable todas las excepciones y errores
• Se utiliza la palabra clave throws en la declaración del método
• Lo más genérico es imprimir la traza de la pila de llamadas y así
se ve dónde ha ocurrido
public void miMétodo() throws Exception{
//código que puede lanzar una excepción e
}
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
public void miMétodo(){
try{
//código
}catch(Throwable e){
System.out.println(e.printStackTrace());
}
}
13
Definición de nuevas excepciones (de usuario)
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
14
Cómo lanzar excepciones
Basta con heredar de la clase Exception
Para lanzar una nueva excepción:
1.
Crear la excepción con new ClaseExcepción
2.
Usar la palabra clave throw
Exception
public class Banco{
public Cuenta crearCuenta (String cliente)
throws CuentaRechazada
{
if (!listaNegra.esta(cliente))
return new Cuenta(cliente);
else
throw new cuentaRechazada();
}
}
ExcepciónJuego
ExcepciónJugadaInválida
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
ExcepciónJugadorAusente
Excepciones
15
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
16
Ventajas del mecanismo de excepciones
readFile {
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
}
Separación del tratamiento de errores del resto del código
del programa
Ejemplo de código sin tratamiento de errores
Flujo del programa más sencillo
Evita manejos de códigos de error
Propagación de errores a lo largo de la pila de llamadas a
métodos
Evitar retornos continuos en caso de error
Evitar la necesidad de argumentos adicionales
• Por ejemplo, el clásico boolean
Agrupamiento y definición de tipos de errores como clases
Jerarquías de excepciones
Tratar errores a diferentes niveles de especificidad
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
17
Ejemplo de tratamiento de errores sin excepciones
errorCodeType readFile {
initialize errorCode = 0;
open the file;
if (theFileIsOpen) {
determine the length of the file;
if (gotTheFileLength) {
allocate that much memory;
if (gotEnoughMemory) {
read the file into memory;
if (readFailed) errorCode = -1;
}
else errorCode = -2;
}
else errorCode = -3;
close the file;
if (theFileDidntClose && errorCode == 0)
errorCode = -4;
else errorCode = errorCode & -4;
}
else errorCode = -5;
return errorCode;
}
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
18
Ejemplo de tratamiento de errores con excepciones
public void leeFichero (File f) {
try {
abre(f);
determina_tamaño(f);
asigna_memoria(tam);
lee_fichero_en_memoria(f);
cierra(f);
}
catch (fileOpenFailed) { doSomething; }
catch (sizeDeterminationFailed) { doSomething; }
catch (memoryAllocationFailed) { doSomething; }
catch (readFailed) { doSomething; }
catch (fileCloseFailed) { doSomething; }
}
19
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
20
Ejercicio
Excepciones en C++
Realizar un programa en el que haya una ventana con un
campo de texto donde se pueda introducir un número y el
programa saque en la ventana su raíz cuadrada
Manejando excepciones tratar las siguientes situaciones:
Mecanismo no original del lenguaje, incorporado en las
versiones más recientes
Utiliza el mismo mecanismo que Java, en tres fases:
Intento de ejecución de un bloque de código
try {
// bloque de código-intento
...
}
Si se produce una circunstancia excepcional durante la
ejecución se lanza la excepción
if (condicion) throw "overflow";
La ejecución del programa se desvia a un sitio específico
donde la excepción es capturada y se trata
catch (...) { // bloque manejador de posibles
excepciones
...
}
• Se introduce un número negativo
• Se introduce un texto que no es un número
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
21
Excepciones en C++
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Ejemplo: supóngase que quiere crearse un array de cien
millones de enteros
Ejemplo: no vale con intentar un if..else
#include <iostream>
using namespace std;
int main() {
int *x = 0;
int y = 100000000;
int main() {
int *x = NULL;
int y = 100000000;
x = new int[y]; // fallará al hacer el new, nada puede salvarlo
if(x) {
x[10] = 0;
cout << "Puntero: " << (void *) x << endl;
delete[] x;
} else {
cout << "Memoria insuficiente." << endl;
}
cin.get();
return 0;
x = new int[y]; // crash!!!!
x[10] = 0;
cout << "Puntero: " << (void *) x << endl;
delete[] x;
cin.get();
return 0;
}
Normalmente habrá un momento en que no quedará memoria y
el programa abortará
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
22
Excepciones en C++
#include <iostream>
using namespace std;
Excepciones
Excepciones
}
23
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
24
Excepciones en C++
Excepciones en C++
Ejemplo: con excepciones se puede tratar el problema
Clase base
class exception {
public: exception() throw() { }
virtual ~exception() throw();
virtual const char* what() const throw();
};
#include <iostream>
using namespace std;
int main() {
int *x;
int y = 100000000;
• La función what() debe devolver una cadena que indica la razón
de la excepción
try {
x = new int[y];
x[0] = 10;
cout << "Puntero: " << (void *) x << endl;
delete[] x;
}
catch(std::bad_alloc&) {
cout << "Memoria insuficiente" << endl;
}
Existe una forma de capturar cualquier excepción
catch(...) {
cout << "Excepción imprevista" << endl;
}
cin.get();
return 0;
}
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
25
Excepciones en C++
Excepciones
26
Excepciones en C++
Ejemplo: excepciones en copia de ficheros
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Primero: definición de la clase de excepción
Ejemplo: excepciones en copia de ficheros
Primero: definición de la clase de excepción
• Definición del método what()
#include <iostream>
#include <fstream>
using namespace std;
const char* CopiaEx::what() const throw() {
switch(motivo) {
case 1:
return "Fichero de origen no existe";
case 2:
return "No es posible abrir el fichero de
salida";
}
return "Error inesperado";
}
class CopiaEx: public exception {
public:
CopiaEx(int mot) : exception(), motivo(mot) {}
const char* what() const throw();
private:
int motivo;
};
Ejemplo de C++ con Clase: http://www.conclase.net/c/curso/index.php?cap=043b
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
27
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
28
Excepciones en C++
Excepciones en C++
Ejemplo: excepciones en copia de ficheros
Utilización en el programa
Ejemplo: excepciones en copia de ficheros
• Cómo lanzar excepciones
• Cómo capturar y tratar excepciones
void CopiaFichero(const char* Origen, const char *Destino) {
unsigned char buffer[1024];
int leido;
ifstream fe(Origen, ios::in | ios::binary);
if(!fe.good()) throw CopiaEx(1);
int main() {
char Desde[] = "excepcion.cpp"; // Este fichero
char Hacia[] = "excepcion.cpy";
try {
CopiaFichero(Desde, Hacia);
}
catch(CopiaEx &ex) {
cout << ex.what() << endl;
} // (2)
cin.get();
return 0;
ofstream fs(Destino, ios::out | ios::binary);
if(!fs.good()) throw CopiaEx(2);
do {
fe.read(reinterpret_cast<char *> (buffer), 1024);
leido = fe.gcount();
fs.write(reinterpret_cast<char *> (buffer), leido);
} while(leido);
fe.close();
fs.close();
}
}
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
29
Excepciones en C++ y Java
En C++ no es necesario declarar previamente las excepciones (en Java
si no son Runtime, sí)
Los objetos de excepción pueden ser de cualquier tipo
Valen también tipos primitivos como int o bool
Se puede definir una clase de excepción que no herede de ninguna predefinida
class error_limites {
public :
int lim_inferior ;
int lim_superior ;
int valor ;
error_limites(int inf, int sup, int v) {
lim_inferior=inf;
lim_superior=sup;
valor=v;
}
}
//… ejemplo de uso:
if ( nota < 0 || nota > 10 )
throw error_limites (0, 10, nota);
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Utilización en el programa
Excepciones
31
Juan Pavón Mestras
Facultad de Informática UCM, 2006-07
Excepciones
30
Descargar