1. 4. Excepciones
¿Qué son las excepciones?
Detección de errores
Manejo de excepciones en Java
Finally y relanzamiento de excepciones
Jerarquía de excepciones
Excepciones implícitas y explícitas
Obtención de información de una excepción
Ejemplos y ejercicios propuestos
Programación III Tema 4 - Excepciones
2. ¿Qué son las excepciones?
(1/2)
• Si una operación no puede completarse
debido a un error, el programa deberá:
– Volver a un estado estable y permitir otras
operaciones.
– Intentar guardar el trabajo y finalizar.
• Esto es difícil debido a que generalmente, el
código que detecta el error no es el que
puede realizar dichas tareas.
• Entonces, el que detecta el error debe
informar al que pueda manejarlo.
Programación III Tema 4 - Excepciones
3. ¿Qué son las excepciones?
• (2)
La solución más habitual a esto son los retornos de códigos
de error. Esto presenta una serie de inconvenientes:
– No siempre queda sitio para códigos de error (p. ej.: getchar).
– No se garantiza que se vayan a consultar. No es obligatorio recoger
un valor de retorno.
– Si se contemplan todos los errores, el código crece demasiado.
– La lógica del programa queda oscurecida.
– No sirven en los constructores donde no se devuelve nada.
• En definitiva, hacen que el tratamiento de errores sea
complejo y que a menudo no se traten todos los errores.
• Java ofrece una solución, otra forma de tratar con los
errores: las excepciones .
• Definición:
– Una excepción es un evento excepcional que ocurre durante la
ejecución del programa y que interrumpe el flujo normal de las
sentencias.
– Es un mecanismo de control de flujo generalmente usado para
tratamiento de situaciones EXCEPCIONALES (como errores por
ejemplo).
Programación III Tema 4 - Excepciones
4. Detección de errores (1/2)
• Una condición excepcional es aquella que impide la
continuación de una operación.
• En Java, cuando ocurre algo así, se lanza una
excepción (throw) para que alguien que sepa
manejarla la trate en un contexto superior.
– Por ejemplo:
if ( “error de CRC” )
throw new IOException();
– Con la palabra THROW se lanza una excepción.
• Cuando ocurre esto, se interrumpe la ejecución habitual del
método y se lanza un objeto que facilite información sobre el
error ocurrido.
• Normalmente se utilizará una clase diferente para cada tipo de
error. Dicha clase deberá contener toda la información necesaria
para tratar de forma correcta dicho error y conocer lo ocurrido.
Programación III Tema 4 - Excepciones
5. Detección de errores (2/2)
• Java obliga a que un método informe de las excepciones
(explícitas) que puede lanzar.
– Un método no sólo tiene que decir qué devuelve si todo va bien,
también debe indicar qué puede fallar.
– Un método especifica las excepciones que se pueden producir en él
mediante la palabra THROWS en la declaración del método.
– Por ejemplo:
void f() throws EOFException,
FileNotFoundException
{
if( ... )
throw new EOFException();
if( ... )
throw new FileNotFoundException();
}
Programación III Tema 4 - Excepciones
6. Manejo de excepciones
(1/6)
• Una vez que se detecta un error hace falta indicar quién se
encarga de tratarlo.
– Para manejar excepciones hay que utilizar las palabras clave TRY y
CATCH.
• El TRY delimita el grupo de sentencias que pueden producir
excepciones.
• El bloque CATCH es el lugar al que se transfiere el control si
alguna de las operaciones produce una excepción.
try{
// Operaciones que pueden “fallar”: que
// pueden producir alguna excepción.
}
catch( <tipoDeExcepción> ref ){
// Tratamiento de esa excepción
}
Programación III Tema 4 - Excepciones
7. Manejo de excepciones
(2/6)
• Por ejemplo:
try{
a.abreFichero();
a.leeCabecera();
a.actualizaDatos();
}
catch( IOException ref ){
System.out.println( “Error de E/S” );
}
– Si alguna de las operaciones del bloque produce una excepción, se
interrumpe el bloque try y se ejecuta el catch. Al finalizar éste, se
continúa normalmente.
– Si no se produce ninguna excepción el bloque catch se ignora.
Programación III Tema 4 - Excepciones
8. Manejo de excepciones
(3/6)
• Un bloque try puede tener varios catch asociados, uno para cada tipo
de excepción que se pueda producir.
– Por ejemplo:
try{
a.abreFichero();
a.leeCabecera();
a.actualizaDatos();
}
catch( FileNotFoundException ref ){
System.out.println( “Error de apertura” );
}
catch( IOException ref ){
System.out.println( “Error de E/S” );
}
Programación III Tema 4 - Excepciones
9. Manejo de excepciones
(4/6)
• Si se produce una excepción que no se corresponde con ningún catch indicado, la excepción se propaga
hacia atrás en la secuencia de invocaciones hasta encontrar un catch adecuado.
• Por ejemplo:
void f1( int accion ) throws EOFException
{
try{
if( accion == 1 )
throw new FileNotFoundException();
else if( accion == 2 )
throw new EOFException();
}
catch( FileNotFoundException e ){
System.out.println( “Error corregido” );
}
System.out.println(“Finalización normal de f1”);
}
void f2( int accion )
{
try{
f1( accion ):
}
catch( EOFException e ){
System.out.println( “Error corregido” );
}
System.out.println(“Finalización normal de f2”);
}
Programación III Tema 4 - Excepciones
10. Manejo de excepciones
(5/6)
– ¿ Qué pasa si se llama a f2 pasándole los valores
1 ó 2 para el parámetro acción? ¿En qué método
se producen las excepciones y en cuál se tratan?
• Cuando se invoca a un método que lanza
excepciones, es obligatorio:
– Que se maneje el error (en un catch).
– O que se indique mediante throws su
propagación.
Programación III Tema 4 - Excepciones
11. Manejo de excepciones
(6/6)
• Por ejemplo:
void f1() throws IOException
{
...
}
//ALTERNATIVA 1: TRATAR EL ERROR EN CUANTO SE PRODUCE
void f2()
{
try{
f1()
}
catch( IOException e ){
// Tratamiento del error
}
}
//ALTERNATIVA 2: SE CONTINUA PROPAGANDO EL ERROR
//PARA QUE LO GESTIONE OTRO METODO
void f2() throws IOException
{
f1();
}
Programación III Tema 4 - Excepciones
12. Finally (1/3)
• Puede haber ocasiones en que se desea realizar alguna
operación tanto si se producen excepciones como si no.
• Dichas operaciones se pueden situar dentro de un bloque
FINALLY.
try{
// Operaciones con posibles
excepciones
}
catch( <tipoDeExcepcion> ref ){
// Tratamiento de la excepción
}
finally{
// Operaciones comunes
}
Programación III Tema 4 - Excepciones
13. Finally (2/3)
• Ejemplo:
class Recurso
{
void reserva() throws ExceptionA, ExceptionB,
ExceptionC { ... }
void libera() { ... }
}
class Ejemplo
{
void prueba()
{
Recurso recurso = new Recurso();
try{
recurso.reserva();
// Operaciones con posibles excepciones
}
catch( ExceptionA a ){// Tratamiento del error}
catch( ExceptionB b ){// Tratamiento del error}
catch( ExceptionC c ){// Tratamiento del error}
finally{
recurso.libera();
}
}
}
Programación III Tema 4 - Excepciones
14. Finally (3/3)
• Si no se produce ninguna excepción, se
ejecutarán el bloque try y el finally.
• En cambio, si se produce alguna excepción:
– Si es atrapada por un catch del mismo try, se
ejecuta éste y luego el finally. La ejecución
continúa después del finally con normalidad.
– Si no es atrapada, se ejecuta el finally y la
excepción se propaga al contexto anterior.
Programación III Tema 4 - Excepciones
15. Relanzamiento de
excepciones
• Hay situaciones en las que interesa relanzar
una excepción ya atrapada.
• Interesa dar un tratamiento determinado a
una excepción pero también interesa seguir
propagándola hacia arriba para que en un
contexto superior se siga teniendo constancia
de ella.
catch( Exception e ){
// Tratar excepción y propagar
throw e;
}
Programación III Tema 4 - Excepciones
16. Jerarquía de excepciones
(1/4)
• Toda excepción debe ser una instancia de
una clase derivada de la clase Throwable.
• De ella hereda una serie de métodos que dan
información sobre cada excepción.
– getMessage
– toString
– printStackTrace (imprime en la salida estándar un
volcado de la pila de llamadas).
Programación III Tema 4 - Excepciones
17. Jerarquía de excepciones
(2/4)
• La jerarquía de excepciones en Java es la siguiente:
Programación III Tema 4 - Excepciones
18. Jerarquía de excepciones
(3/4)
– Las clases derivadas de Error describen errores
internos de la JVM (errores serios) que la
aplicación no debería intentar gestionar.
• Ejemplos: OutOfMemoryError, StackOverflowError,
etc.
– Los programas en Java trabajarán con las
excepciones de la rama Exception. Estas
excepciones se clasifican en:
– Explícitas: las que derivan directamente de Exception.
– Implícitas: las que derivan de RunTimeException.
Programación III Tema 4 - Excepciones
19. Jerarquía de excepciones
(4/4)
– Se utilizan las RunTimeException (implícitas) para indicar
un error de programación = interno. Si se produce una
excepción de este tipo hay que arreglar el código.
• Por ejemplo: un cast incorrecto, acceso a un array fuera de
rango, uso de un puntero null, etc.
– El resto de las Exception (explícitas) indican que ha
ocurrido algún error ajeno al programa.
• Por ejemplo: un error de E/S, error de conexión, etc.
• Los métodos deben declarar (throws) sólo las
excepciones explícitas.
• Las implícitas no hay que declararlas (throws). El
error suele ser del programador por lo que no se
recomienda su tratamiento, sino corregir el código
para que no se produzcan.
Programación III Tema 4 - Excepciones
20. Creación de excepciones
(1/5)
• En Java se pueden crear nuevas clases de
Excepciones.
– La única condición es que la clase derive de la clase
Throwable o de alguna derivada.
• En la práctica, normalmente derivará:
– de RuntimeException si se desea notificar un error de
programación.
– de Exception en cualquier otro caso.
• Cuestiones
– En un método que tiene como parámetro un entero
entre 1 y 12 se recibe un 14 ¿Qué tipo de excepción se
crearía para notificarlo?
– Si un método para listar Clientes por impresora se
encuentra con que deja de responder, ¿qué tipo de
excepción debería crear?
Programación III Tema 4 - Excepciones
21. Creación de excepciones
(2/5)
• Ejemplo de creación y lanzamiento de una excepción explícita:
class PrinterException extends Exception{}
class Ejemplo
{
void imprimirClientes( Cliente[] clientes ) throws
PrinterException
{
for( int i=0; i<clientes.length; i++ )
{
//Imprimir cliente[i]
if( “error impresión” )
throw new PrinterException();
}
}
void informe()
{
try{
imprimirClientes(clientes)
}
catch(PrinterExcepcion e){
System.out.println(“Error al imprimir”);
}
}
}
Programación III Tema 4 - Excepciones
22. Creación de excepciones
(3/5)
– El método imprimirClientes debe declarar que
puede lanzar la excepción PrinterExceptión
porque es una excepción explicita.
– Además, el compilador nos obliga a que el
código que llame al método imprimirClientes
debe capturar la posible excepción (o en caso
contrario relanzarla (throws)).
Programación III Tema 4 - Excepciones
23. Creación de excepciones
(4/5)
• Ejemplo de creación y lanzamiento de una excepción implícita:
class MesInvalidoException extends RuntimeException
{}
class Fecha
{
void setMes( int mes )
{
if( mes < 1 || mes > 12 )
throw new MesInvalidoException();
}
}
class Ejemplo
{
public static void main( String[] args )
{
Fecha fecha = new Fecha();
fecha.setMes(14);
}
}
Programación III Tema 4 - Excepciones
24. Creación de excepciones
(5/5)
– En este ejemplo no es obligatorio declarar que se lanza
una excepción porque es de tipo RuntimeException
(implícita).
– Además, tampoco es obligatorio capturarla.
• Java obliga a atrapar las excepciones explícitas,
¿Qué pasa si no se atrapa una implícita como en
este caso?
– El programa compila correctamente.
– Al invocar el método setMes( ) con el valor 14, se
produce la excepción, se propaga al main y como no ha
sido capturada el main la pasa al proceso principal (la
JVM). El programa finaliza de una forma anormal pero
al menos la JVM en su tratamiento por defecto muestra
un mensaje y el sistema no se “cuelga”.
– El programador debe darse cuenta de que existe un error
en el código que llama al método setMes( ).
Programación III Tema 4 - Excepciones
25. Resumen de excepciones
explícitas-implícitas
• Excepciones explícitas:
– Derivan de Exception (no de RuntimeException).
– Indican un error externo a la aplicación.
– Si se lanzan y no se capturan es obligatorio declararlas.
– Si se invoca un método que las lanza, es obligatorio o
atraparlas o declararlas para ser lanzadas.
• Excepciones implícitas:
– Derivan de RuntimeException.
– Indican un error de programación.
– No hay por qué declararlas: se deben corregir.
– Su captura es opcional.
Programación III Tema 4 - Excepciones
26. Obtención de información de
una excepción
• Una excepción, como cualquier otra clase, puede
tener operaciones (métodos get/set) que permitan
obtener más información sobre el error. Toda
excepción tiene unos métodos útiles.
– public String getMessage( )
• Devuelve el mensaje detallado de error de la excepción.
– public String toString( )
• Devuelve la representación String del error.
– public void printStackTrace( )
• Visualiza en la salida estándar la traza de llamadas causantes el
error.
Programación III Tema 4 - Excepciones
27. Ejemplos
• Ejemplo 1: Lectura de un número por teclado
• Ejemplo 2: Incorporación de excepciones a
Fraccion
• Ejemplo 3: Incorporación de excepciones a
ListaEnlazada
Programación III Tema 4 - Excepciones
28. Ejercicios propuestos (1/2)
• Ejercicio 1: División por cero
– Escribe una clase llamada DividePorCero que
pruebe a dividir un entero entre otro recogiendo
la excepción de división por cero y mostrando el
mensaje "Error: división por cero" si se produce.
Programación III Tema 4 - Excepciones
29. Ejercicios propuestos (2/2)
• Ejercicio 2: Clase Fracción
– Diseña e implementa una clase Fraccion que permite
crear fracciones (numerador y denominador enteros),
con métodos para sumar, restar, multiplicar y dividirlas.
– Crea una excepción FraccionException que se lance
siempre que en una operación de fracción se produzca
un error, a saber:
• Creación de una fracción con denominador cero.
• División de una fracción entre otra con numerador cero.
• Cualquier operación que incluya una fracción con denominador
cero.
– Hacer que cada operación crítica lance esta excepción si
se produce, con un mensaje indicativo del tipo de error
(mensaje incluido en la excepción, no salida a pantalla!).
Probar la clase.
Programación III Tema 4 - Excepciones