Programación Orientada a
Objetos
Unidad 4
Excepciones
Universidad de Chile
Departamento de Ciencias de la Computación
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
2
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
Solución 1
import [Link].*;
public class Program6 {
public static void main(String args[ ]) {
int nc = [Link]("Cuantos candidatos ? ");
int count[] = new int[nc], nv = 0;
for (int i=0; i < cand; i++) count[i] = 0;
while (true) {
int c = [Link](“numero candidato ? “);
if (c == 0) break;
nv++; count[c - 1]++;
}
for (int i=0; i < nc; i++)
[Link](“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 ?
4
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
5
Solución 2 No importa el tipo de error
import [Link].*;
public class Program6 {
public static void main(String args[ ]) {
int nc = [Link]("Cuantos candidatos ? ");
int count[] = new int[nc], nv = 0;
for (int i=0; i < cand; i++) count[i] = 0;
while (true) {
try {
int c = [Link](“numero candidato ? “);
if (c == 0) break;
nv++; count[c - 1]++; [Link](“OK”);
} catch (Exception e) {
[Link](“Error, dato se ignora “);
}
}
for (int i=0; i < nc; i++)
[Link](“Candidato "+(i+1)+" obtuvo "+(100*count[i]/nv)+"%");
}
}
6
Solución 3 Si importa el tipo de error
import [Link].*;
public class Program6 {
public static void main(String args[ ]) {
int nc = [Link]("Cuantos candidatos ? ");
int count[] = new int[nc], nv = 0;
for (int i=0; i < cand; i++) count[i] = 0;
while (true) {
try {
int c = [Link](“numero candidato ? “);
if (c == 0) break;
nv++; count[c - 1]++; [Link](“OK”);
} catch (InputMismatchException e) {
[Link](“Error, dato se ignora “);
} catch (ArrayIndexOutOfBoundException e) {
[Link](“Error, dato se ignora “);
}
}
for (int i=0; i < nc; i++)
[Link](“Candidato "+(i+1)+" obtuvo "+(100*count[i]/nv)+"%");
}
}
7
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)
8
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
9
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;
}
10
Ventaja 1: Limpieza del Código
Agregando manejo de errores
int leerArchivo { ...
codError = 0; } else {
abrir el archivo; codError = -3;
if (archivo abierto) { }
determinar su tamaño; cerrar el archivo;
if (tamaño determinado) { if (error al cerrar archivo) {
crear la memoria necesaria; codError = -4;
if (memoria suficiente) { }
leer el archivo a memoria; } else {
if (error de lectura) { codError = -5;
codError = -1; }
} return codError;
} else { }
codError = -2;
}
...
11
Ventaja 1: Limpieza del Código
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;
}
} 12
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(); ...
}
13
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() { int metodo2() { int metodo3() {
if (metodo2() != 0) { int err = metodo3(); int err = leerArchivo();
manejar el error; if (err == 0) { if (err == 0) {
} else { ... ...
... } }
} return err; return err;
} } }
14
Ventaja 2: Propagación Errores
Usando excepciones, la propagación de
errores es automática
void metodo1() { void metodo2() {
try { metodo3();
metodo2(); ...
... }
} catch (Exception e) {
manejar el error; void metodo3() {
} leerArchivo();
} ...
}
15
Ventaja 3: Agrupación Errores
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) {
...
}
16
Manejo de Excepciones
Connection conn = null;
try {
// conexión a base de datos
conn = [Link](…);
// uso de conn
// ...
} catch(SQLException e) {
// manejo de error
[Link](…);
} finally {
// liberación de recursos
if (conn != null) {
[Link]();
}
} 17
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
}
18
Propagando Excepciones
void executeQuery() throws SQLException {
Connection conn = null;
try {
// conexión a base de datos
conn = [Link](…);
// uso de conn
// ...
} finally {
// liberación de recursos
if (conn != null) {
[Link]();
}
}
}
19
Jerarquía de Excepciones
20
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)
21
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
22
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
23
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
24
Lanzamiento de Excepciones
Para lanzar una excepción se utiliza la
sentencia throw
void generaReporte() throws UsuarioRequeridoException
{
...
if (usuario == null) {
throw new UsuarioRequeridoException();
}
...
}
25
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
26
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
27