2. 2
Temario
Introducción
Ventajas de excepciones
Manejo de excepciones
Propagación de excepciones
La jerarquía de excepciones
Excepciones "Checked" y "Unchecked“
Creación de clases de excepciones
Lanzamiento de excepciones
3. Problema
Se requiere calcular el % de votos de
los candidatos en una votación cuando
la urna se abre al final del día
Los candidatos están identificados por
un número del 1 al n
Cada vez que se abre un voto se
ingresa el número del candidato votado
Cuando se terminan los votos se
ingresa un 0
3
4. 4
import java.util.*;
public class Program6 {
public static void main(String args[ ]) {
int nc = U.readInt("Cuantos candidatos ? ");
int count[] = new int[nc], nv = 0;
for (int i=0; i < cand; i++) count[i] = 0;
while (true) {
int c = U.nextInt(“numero candidato ? “);
if (c == 0) break;
nv++; count[c - 1]++;
}
for (int i=0; i < nc; i++)
U.println(“Candidato "+(i+1)+" obtuvo "+(100*count[i]/nv)+"%");
}
}
¿ Qué pasa las ingresar algo que no es un número o un número de
candidato erróneo ?
Solución 1
5. 5
Excepciones
Java utiliza excepciones para proveer
capacidades de manejo de errores
Una excepción es un evento que ocurre
durante la ejecución de un programa, y
que interrumpe el flujo normal de
instrucciones
6. 6
import java.util.*;
public class Program6 {
public static void main(String args[ ]) {
int nc = U.readInt("Cuantos candidatos ? ");
int count[] = new int[nc], nv = 0;
for (int i=0; i < cand; i++) count[i] = 0;
while (true) {
try {
int c = U.nextInt(“numero candidato ? “);
if (c == 0) break;
nv++; count[c - 1]++; U.println(“OK”);
} catch (Exception e) {
U.print(“Error, dato se ignora “);
}
}
for (int i=0; i < nc; i++)
U.println(“Candidato "+(i+1)+" obtuvo "+(100*count[i]/nv)+"%");
}
}
Solución 2 No importa el tipo de error
7. 7
import java.util.*;
public class Program6 {
public static void main(String args[ ]) {
int nc = U.readInt("Cuantos candidatos ? ");
int count[] = new int[nc], nv = 0;
for (int i=0; i < cand; i++) count[i] = 0;
while (true) {
try {
int c = U.nextInt(“numero candidato ? “);
if (c == 0) break;
nv++; count[c - 1]++; U.println(“OK”);
} catch (InputMismatchException e) {
U.print(“Error, dato se ignora “);
} catch (ArrayIndexOutOfBoundException e) {
U.print(“Error, dato se ignora “);
}
}
for (int i=0; i < nc; i++)
U.println(“Candidato "+(i+1)+" obtuvo "+(100*count[i]/nv)+"%");
}
}
Solución 3 Si importa el tipo de error
8. 8
Manejo de Excepciones
Sintaxis
try {
// código que puede generar
// excepciones
} catch(ExceptionType1 e) {
// acciones para manejar la excepción
} catch(ExceptionType2 e) {
// acciones para manejar la excepción
} finally {
// código que se ejecuta siempre,
// haya o no una excepción
}
catch y finally son bloques opcionales (pero uno de los dos
debe estar presente acompañando al bloque try)
9. 9
Ventajas de Excepciones
En comparación con las técnicas tradicionales
de manejo de errores, el manejo de
excepciones provee las siguientes ventajas:
Separación entre el "código normal" y el código de
manejo de errores
Propagación de errores hacia "arriba" en el stack
de llamadas (y detención automática del programa
si una situación de error no es manejada)
Facilidades para la agrupación de tipos de errores
Facilidades para entregar información del error
producido, sin que se produzca interferencia con
el retorno normal
10. 10
Ventaja 1: Limpieza del Código
Supongamos que queremos leer un
archivo a memoria, el seudocódigo
podría ser
leerArchivo {
abrir el archivo;
determinar su tamaño;
crear la memoria necesaria;
leer el archivo a memoria;
cerrar el archivo;
}
11. 11
Agregando manejo de errores
int leerArchivo {
codError = 0;
abrir el archivo;
if (archivo abierto) {
determinar su tamaño;
if (tamaño determinado) {
crear la memoria necesaria;
if (memoria suficiente) {
leer el archivo a memoria;
if (error de lectura) {
codError = -1;
}
} else {
codError = -2;
}
...
...
} else {
codError = -3;
}
cerrar el archivo;
if (error al cerrar archivo) {
codError = -4;
}
} else {
codError = -5;
}
return codError;
}
Ventaja 1: Limpieza del Código
12. 12
Usando excepciones
leerArchivo {
try {
abrir el archivo;
determinar su tamaño;
crear la memoria necesaria;
leer el archivo a memoria;
} catch (error al abrir archivo) {
...
} catch (error al obtener tamaño archivo) {
...
} catch (error al crear memoria) {
...
} catch (error al leer archivo) {
...
} catch (error al cerrar archivo) {
...
} finally {
cerrar el archivo;
}
}
Ventaja 1: Limpieza del Código
13. 13
Ventaja 2: Propagación Errores
Supongamos que el método leerArchivo es el
cuarto de una serie de invocaciones anidadas
metodo1() {
metodo2(); ...
}
metodo2() {
metodo3(); ...
}
metodo3() {
leerArchivo(); ...
}
14. 14
Ventaja 2: Propagación Errores
Supongamos que el primer método es el
interesado en manejar un posible error del
método leerArchivo
void metodo1() {
if (metodo2() != 0) {
manejar el error;
} else {
...
}
}
int metodo3() {
int err = leerArchivo();
if (err == 0) {
...
}
return err;
}
int metodo2() {
int err = metodo3();
if (err == 0) {
...
}
return err;
}
16. 16
Las excepciones pueden agruparse jerárquicamente
utilizando herencia
Si se desea atrapar excepciones de tipo
InvalidIndexException:
catch (InvalidIndexException e) {
...
}
Si se desea atrapar todas las excepciones de
arreglos, independiente de su tipo específico:
catch (ArrayException e) {
...
}
Ventaja 3: Agrupación Errores
17. 17
Connection conn = null;
try {
// conexión a base de datos
conn = DriverManager.getConnection(…);
// uso de conn
// ...
} catch(SQLException e) {
// manejo de error
System.out.println(…);
} finally {
// liberación de recursos
if (conn != null) {
conn.close();
}
}
Manejo de Excepciones
18. 18
Propagación de Excepciones
Si un método no atrapa (catch) una
excepción, el método aborta, propagando la
excepción
Un método debe declarar el conjunto de
excepciones "checked" que lanza o propaga,
con la sentencia throws
void miMetodo() throws ExceptionType {
// código que puede generar excepciones
}
19. 19
void executeQuery() throws SQLException {
Connection conn = null;
try {
// conexión a base de datos
conn = DriverManager.getConnection(…);
// uso de conn
// ...
} finally {
// liberación de recursos
if (conn != null) {
conn.close();
}
}
}
Propagando Excepciones
21. 21
Dos Tipos de Excepciones
Excepciones "checked"
Si un método genera (throw) o propaga
una excepción checked, debe declararlo
(throws) en su firma
Excepciones "unchecked"
No es necesario que un método declare
(throws) las excepciones unchecked que
genera (throw) o propaga (aunque puede
hacerlo)
22. 22
Excepciones "Checked"
Clases derivadas de Throwable, exceptuando
aquellas derivadas de Error y
RuntimeException
El compilador exige que un método declare el
conjunto de excepciones "checked" que lanza
o propaga
void f() throws IOException, SQLException {
...
}
Ejemplos
FileNotFoundException
SQLException
23. 23
Excepciones "Unchecked"
Clases Error, RuntimeException, y derivadas
El compilador no exige que un método
declare las excepciones unchecked que
genera o propaga, de modo de no complicar
la programación
Ejemplos
OutOfMemoryException
NullPointerException
ArrayIndexOutOfBoundsException
24. 24
Creación de Excepciones
Parte del diseño de un paquete es la definición
de las excepciones que su uso puede generar
Para crear un nuevo tipo de excepciones, debe
crearse una clase derivada de Throwable
Para definir excepciones checked, lo
aconsejable es derivarlas de la clase Exception
public class UsuarioRequeridoException extends Exception {
public UsuarioRequeridoException() {
super("Debe establecerse el usuario!");
}
}
Para definir excepciones unchecked, lo
aconsejable es derivarlas de la clase
RuntimeException
25. 25
Lanzamiento de Excepciones
Para lanzar una excepción se utiliza la
sentencia throw
void generaReporte() throws UsuarioRequeridoException
{
...
if (usuario == null) {
throw new UsuarioRequeridoException();
}
...
}
26. 26
Resumen
Java permite manejar los errores de una
manera cómoda y segura, utilizando
excepciones
Las excepciones son clases derivadas de la
clase Throwable
El bloque try-catch-finally permite programar
separadamente el código normal y el manejo
de errores
Las excepciones no atrapadas en un bloque
catch son automáticamente propagadas al
método "anterior" en el stack de llamadas
27. 27
Resumen
Si una excepción no es atrapada en un
programa, éste aborta
Un método debe declarar en la cláusula
throws de su firma el conjunto de
excepciones "checked" que lanza o propaga,
lo que no es necesario para las excepciones
"unchecked" (derivadas de las clases Error y
RuntimeException)
Se recomienda que las excepciones propias
se deriven de las clases Exception (checked)
o RuntimeException (unchecked)
Para lanzar una excepción se utiliza la
sentencia throw