Manejo de Excepciones

Anuncio
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
Manejo de Excepciones
Una excepción en java es un evento que ocurre durante la ejecución de un
programa que interrumpe el flujo normal de las instrucciones. Una excepción
puede ser causada por fallas de hardware o por errores sencillos de
programación como tratar de acceder a un elemento inexistente de un arreglo.
Cuando dentro de un método de Java ocurre un error, como los que se
describieron anteriormente, el método crea un objeto tipo excepción y se lo
entrega al sistema de ejecución. Este objeto de excepción contiene información
sobre la excepción como lo es su tipo y el estado del programa cuando ocurrió
el error. En Java se dice que ésto es lanzar una excepción.
Una vez que un método lanzó una excepción, el sistema de ejecución se
encarga de encontrar un método manejador de excepciones para atender la
excepción. El conjunto de métodos que posiblemente podrán atender a la
excepción son aquellos que estan en la pila de llamadas a métodos en el
momento en que se presentó la excepción. El sistema de ejecución realiza su
busqueda desde el método mas reciente hasta llegar al mas antiguo. El
manejador de excepciones buscado es aquel que sea del mismo tipo que la
excepción. Cuando se selecciona un manejador se dice que se ha atrapado la
excepción. Si se recorren todos los métodos en la pila y no se encuentra un
manejador apropiado, entonces el programa terminará.
Ventajas de Utilizar Excepciones
Separar el Código de Manejador de Errores
La forma tradicional de atender condiciones de error mezcla el código del
programa con el código utilizado para manejar errores. Esto provoca que se
dificulte la lectura del código principal. El sistema de excepciones de Java
permiten separar claramente los dos tipos de código incrementando la
legibilidad del programa. El Listado 1 contiene pseudocódigo que ejemplifica el
uso de excepciones para atrapar errores que pueden presentarse al leer un
archivo.
1 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
leerArchivo {
try {
abrir el archivo
calcular tamaño
asignar memoria
leer el archivo
cerrar el archivo
} catch (noAbrioArchivo) {
hacer algo
} catch (noCalculoTamaño) {
hacer algo
} catch (noAsignoMemoria) {
hacer algo
} catch (noLeyo) {
hacer algo
} catch (noCerroArchivo) {
hacer algo
}
}
Listado 1 Ejemplo de Manejo de Errores con Excepciones
Propagación de Errores en la Pila de Llamadas a Métodos
Otra ventaja del sistema de excepciones es la capacidad para propagar el
reporte de un error por la pila de llamadas a métodos. De esta manera, si a un
método no le interesa atender un error, permite que el error le llegue al método
que si lo atenderá. El Listado 2 ejemplifica la forma de estructurar métodos para
que permita la propagación de errores.
2 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
método1 {
try {
llamar al método2
} catch (excepción) {
procesar error
}
}
método2 throws excepción {
llamar al método3
}
método3 throws excepción {
hacer algo que provoque error
}
Listado 2 Propagación de Errores
Agrupación de Tipos de Errores y Distincción entre Errores
Las excepciones en Java deben ser tipo Throwable o derivadas de esta clase.
Es posible atrapar excepciones especificas, esto es especificando el nombre de
la excepción o de manera mas general atrapando la clase de la que se deriva la
excepción.
La Figura 1 muestra un ejemplo de una jerarquía de clases de excepciones. En
ésta se muestra que la clase ArrayException se deriva de Exception y que
contiene excepciones para atender los casos en los que se utilice un número de
elemento no valido o que no se encuentre el elemento o que el tipo del
elemento no sea el apropiado. El Listado 3 muestra tres ejemplos de como
pueden atenderse excepciones ya se especificando directamente el nombre de
la excepción o de manera mas general especificando una excepción de mayor
jerarquía o finalmente especificando una excepción genérica. Este último
método no es recomendable para todas las excepciones debido a que atraparía
3 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
demasiadas excepciones lo cual podría provocar mas errores. En los tres
casos, el parámetro e se puede utilizar para saber exactamente que tipo de
excepción occurrió.
Figura 1 Jerarquía de Clases de Excepción
catch (InvalidIndexException e) {
. . .
}
catch (ArrayException e) {
. . .
}
catch (Exception e) {
. . .
}
Listado 3 Ejemplos de Manejo de Excepciones
Ejemplo de Manejo de Excepciones
El Listado 4 es un archivo de programa que no compila debido a que emplea
dos métodos que pueden generar excepciones pero no tiene una forma de
atenderlas. El Listado 5 list muestra una forma de corregir el programa para que
si sea posible compilarlo.
4 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
// Note: This class won't compile by design!
// See InputFileDeclared.java for a version of this
// class that will compile.
import java.io.*;
public class InputFile {
private FileReader in;
public InputFile(String filename) {
in = new FileReader(filename);
}
public String getWord() {
int c;
StringBuffer buf = new StringBuffer();
do {
c = in.read();
if (Character.isWhitespace((char)c))
return buf.toString();
else
buf.append((char)c);
} while (c != -1);
return buf.toString();
}
}
Listado 4 InputFile.java No atiende excepciones.
5 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
Excepciones Verificadas
Java tiene distintos tipos de excepciones. Entre ellas están excepciones de E/S,
import java.io.*;
public class InputFileDeclared {
private FileReader in;
public InputFileDeclared(String filename) throws
FileNotFoundException {
in = new FileReader(filename);
}
public String getWord() throws IOException {
int c;
StringBuffer buf = new StringBuffer();
do {
c = in.read();
if (Character.isWhitespace((char)c))
return buf.toString();
else
buf.append((char)c);
} while (c != -1);
return buf.toString();
}
}
Listado 5 Manejo de excepciones correctas.
6 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
excepciones de tiempo de ejecución y excepciones creadas por el usuario. Las
excepciones de tiempo de ejecución pueden ocurrir en cualquier momento y
pueden ser bastantes. Por esta razón, el compilador no tiene como requisito
que se atrapen o especifiquen las excepciones de tiempo de ejecución. Sin
embargo, existe otro tipo de excepciones que son las que si son verificadas por
el compilador. Estas deben ser atrapadas o especificadas para que pueda
compilar.
Atrapar o Especificar
Java indica que un método debe de atrapar o especificar todas las excepciones
verificadas que pueden lanzarse dentro de un método. Atrapar una excepción
significa que se proveerá un manejador de excepciones para este tipo de
excepción. Especificar una excepción significa que un método no va a atender
una excepción por lo que deberá volverla a lanzar para que la atrape un método
que si la atenderá. Ésto pasa a formar parte de la interfaz publica del método
debido a que los métodos que lo llamen deben saber el tipo de excepción que
se lanza para poder tomar decisiones sobre lo que deberá hacer.
Como Atrapar y Manejar Excepciones
El bloque try
Dentro de un bloque try se deben colocar las instrucciones que pueden lanzar
una excepción. Todo bloque try deberá tener al menos un bloque catch o un
bloque finally.
El bloque catch
El bloque catch se especifica inmediatamente después de un bloque try. El
parámetro de un catch debe contener el tipo de la excepción que se atrapa y el
nombre de la variable que representará a la excepción dentro del bloque catch.
Por medio de esta variable se podrán acceder a los métodos de la excepción
para obtener mayor información sobre ella. Un ejemplo es el método
7 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
getMessage(). Se puede utilizar mas de un bloque catch y de esta manera
atrapar distintas excepciones que puedan presentarse.
El bloque finally
El último paso en la atención a excepciones es el de proporcionar una forma
para liberar recursos o cerrar archivos sin importar la excepción que se
presentó. El sistema de ejecución siempre ejecuta el bloque finally sin importar
lo que sucedió en el bloque try.
Ejemplo con Errores
// Note: This class won't compile by design!
// See ListOfNumbersDeclared.java or ListOfNumbers.java
// for a version of this class that will compile.
import java.io.*;
import java.util.Vector;
public class ListOfNumbers {
private Vector victor;
private static final int size = 10;
public ListOfNumbers () {
victor = new Vector(size);
for (int i = 0; i < size; i++)
victor.addElement(new Integer(i));
}
public void writeList() {
PrintWriter out = new PrintWriter(new FileWriter
("OutFile.txt"));
for (int i = 0; i < size; i++)
out.println("Value at: " + i + " = " + victor.elementAt(i));
out.close();
}
}
8 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
Ejemplo Completo
import java.io.*;
import java.util.Vector;
public class ListOfNumbers {
private Vector victor;
private static final int size = 10;
public ListOfNumbers () {
victor = new Vector(size);
for (int i = 0; i < size; i++)
victor.addElement(new Integer(i));
}
public void writeList() {
PrintWriter out = null;
try {
System.out.println("Entering try statement");
out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < size; i++)
out.println("Value at: " + i + " = " + victor.elementAt
(i));
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Caught ArrayIndexOutOfBoundsException:
" +
e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} finally {
if (out != null) {
System.out.println("Closing PrintWriter");
out.close();
} else {
System.out.println("PrintWriter not open");
}
}
}
}
9 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Universidad Autónoma de Baja California
Facultad de Ingeniería
Apuntes de Programación Orientada a Objetos I
Ejemplo 2
import java.io.*;
import java.util.Vector;
public class ListOfNumbersDeclared {
private Vector victor;
private static final int size = 10;
public ListOfNumbersDeclared () {
victor = new Vector(size);
for (int i = 0; i < size; i++)
victor.addElement(new Integer(i));
}
public void writeList() throws IOException,
ArrayIndexOutOfBoundsException {
PrintWriter out = new PrintWriter(new FileWriter
("OutFile.txt"));
for (int i = 0; i < size; i++)
out.println("Value at: " + i + " = " + victor.elementAt(i));
out.close();
}
}
10 de 10
Elaborado por: M.C. Cecilia M. Curlango Rosas
Descargar