Logo Studenta

CLASE 8 - Excepciones [Modo de compatibilidad]

¡Este material tiene más páginas!

Vista previa del material en texto

Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Manejo de excepciones
• Manejo de Errores mediante Excepciones. Tipos de excepciones: 
Exception y RuntimeException
• Manejadores de Excepciones
• La cláusula try/catch
• Búsqueda del manejador apropiado
• Manejadores genéricos y específicos
• La cláusula finally
• Definición de Excepciones propias
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
En Java las excepciones se clasifican en:
• Verificadas en Compilación (checked exception): son errores que el compilador
verifica y que se espera que el programador las maneje en su programa. Por ej.: al
intentar abrir un archivo desde el sistema de archivos, podría dispararse una
excepción, ya que el archivo puede no existir. En ese caso una solución posible es
pedirle al usuario que ingrese un nuevo nombre; otro ejemplo podría ser intentar de
ejecutar una sentencia sql errónea en la base de datos.
• No-Verificadas en Compilación (unchecked exception): representan errores de
programación difíciles de preveer. Son excepciones disparadas automáticamente
por el sistema de ejecución de JAVA. Por ejemplo, las excepciones aritméticas
(división por cero), excepciones de referencias nulas (acceso a un objeto mediante
un puntero nulo), excepciones de indexación (acceso a un elemento de un arreglo
con un índice muy chico ó demasiado grande) y error de casting. JAVA no obliga a
los programadores a manejar este tipo de excepciones.
Manejo de errores - Excepciones
Java usa excepciones para proveer manejo de errores a sus programas. Una
excepción es un evento o problema que ocurre durante la ejecución de un programa
que interrumpe el flujo normal de ejecución de instrucciones. Si una excepción no
cuenta con la información necesaria para resolver el problema en el contexto en que
sucedió se puede pasar el problema a un contexto de más alto nivel.
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Jerarquía de Excepciones
Las objetos de tipo Exception son disparadas cuando ocurren condiciones anormales, que frecuentemente
pueden ser manejadas por un código específico y recuperadas.
Los objetos de tipo Error son disparados por problemas serios, relacionados con la máquina, la memoria o el
procesador. Los errores son disparados por la JVM y los programadores no pueden hacer nada.
ZipExceptionFileNotFoundException
Exception Error
ThreadDeath OutOfMemoryError***
“ unchecked “
(el compilador no chequea)
ArithmeticException NullPointerException***
**
*** MiExceptionIOException
“checked “
(el compilador chequea su manejo)
Las excepciones en JAVA 
son instancias de 
Throwable ó de algún 
descendiente de 
Throwable.Excepciones que 
representan fallas de 
operaciones de I/O
Excepciones que puede ser 
evitadas con código 
preventivo.
Object
Throwable
RunTimeException
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Un ejemplo con majeo de archivos 
(1 de 3)
import java.io.*;
public class InputFile {
private FileReader in;
public InputFile (String filename) {
in=new FileReader(filename);
}
public String getWord() {
int c = 0;
StringBuffer buf = new StringBuffer();
while ((c = in.read()) != -1) {
if (Character.isWhitespace((char) c))
return buf.toString();
else
buf.append((char) c);
}
return buf.toString();
}
}
Si compilamos la clase InputFile, el 
compilador nos da los siguientes dos errores:
InputFile.java: 11: Warning: Exception
java.io.FileNotFoundException must be caught, or it must 
be declared in throws clause of this method.
in=new FileReader(filename);
InputFile.java: 19: Warning: Exception
java.io.IOException must be caught, or it must be declared 
in throws clause of this method.
c=in.read();
El compilador detecta que tanto el
constructor de la clase InputFile como el
método getWord, no especifican ni capturan
las excepciones que se pueden generar
adentro de su alcance, por lo tanto rechaza
la compilación.
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
in=new FileReader(filename); c=in.read();
El nombre pasado como parámetro al 
constructor de la clase FileReader no existe 
en el file system, por lo tanto el constructor 
disparará la excepción: 
java.io.FileNotFoundException.
El método getWord() de nuestra clase InputFile, 
lee del objeto FileReader abierto en el constructor 
de la clase, usando el método read(). Este método 
dispara la excepción: java.io.IOException si por 
algún motivo no se puede leer.
Al disparar estas excepciones, el constructor y el método read() de la clase FileReader (de
la API) permiten que los métodos que los invocan capturen dicho error y lo recuperen de
una manera apropiada.
El compilador JAVA obliga a que toda excepción checked sea capturada ó especificada
por este motivo nuestra clase InputFile no compila.
En este punto tenemos dos opciones:
1) Arreglar al constructor de la clase InputFile y al método getWord() para que
capturen y recuperen el error (usando bloques try-catch), ó
2) Pasar por alto los errores y darle la oportunidad a los métodos que invoquen
al constructor y a los métodos de InputFile de que recuperen los errores
(usando la cláusula throws en el encabezamiento).
Un ejemplo con majeo de archivos 
(2 de 3)
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
import java.io.*;
public class InputFile {
private FileReader in;
public InputFile (String filename) {
try {
in = new FileReader(filename);
} catch (FileNotFoundException e) {
System.out.println(“Error: “+e.getMessage());
}
}
public String getWord() throws IOException {
int c = 0;
StringBuffer buf = new StringBuffer();
while ((c = in.read()) != -1) {
if (Character.isWhitespace((char) c))
return buf.toString();
else
buf.append((char) c);
}
return buf.toString();
}
}
Un ejemplo con majeo de archivos 
(2 de 3)
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Búsqueda de un manejador apropiado
 Cuando un método dispara una excepción, crea un objeto Throwable que es transferido
al sistema de ejecución de JAVA, quién comienza a buscar un manejador de
excepciones adecuado en la pila de ejecución.
 La búsqueda comienza en el método donde se disparó la excepción y luego continúa en la
pila de ejecución de métodos en el orden inverso en que los métodos fueron invocados.
Cuando el sistema de ejecución encuentra un manejador apropiado, le transfiere el control
junto con la excepción lanzada.
 Un manejador de excepciones es adecuado si el tipo de la excepción declarada es del
tipo de la disparada.
Pila de ejecución
Supongamos como muestra la figura que el método
leerArchivo() dispara una IOException: crea
un objeto IOException en la Heap (new); se
interrumpe el flujo normal de ejecución y el objeto
excepción es lanzado del contexto actual.
El sistema de ejecución de Java comienza a buscar
dónde continuar la ejecución: busca un manejador de
la excepción apropiado en la pila de ejecución para
recuperar el problema.
m1(){
m2();
}
m2(){
leerArchivo();
}
leerArchivo() throws IOException{
.........
}
main()
m1()
m2()
leerArchivo()
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Capturar y Manejar Excepciones 
(try/catch)
El bloque try: encierra las sentencias JAVA que podrían disparar excepcionesEl bloque catch: es un bloque de código que implementa el manejador de excepciones 
import java.io.*;
public class EscribirNumerosEntrada {
public static void main(String[] args) {
PrintWriter out = null;
int suma = 0;
try {
out = new PrintWriter(new FileWriter("doc.txt"));
for (int i = 0; i < args.length; i++) {
suma = +Integer.parseInt(args[i]);
}
out.write("La suma es: "+suma);
out.close();
} catch (IOException e1) {
System.err.println("Excepción de IO: " + e1.getMessage());
} catch (NumberFormatException e2) {
System.err.println("Uno de los argumento no es entero:” + e2.getMessage());
} 
}
}
RunTimeException
Exception
El constructor de FileWriter dispara una IOException si el 
archivo es un directorio (en lugar de un archivo regular) y no 
puede crearse ó no puede crearse por alguna razón
El método parseInt() dispara una 
NumberFormatException si el parámetro 
recibido no es un entero.
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
El mecanismo de manejo de excepciones comienza buscando el primer manejador cuyo tipo de argumento
coincida con el tipo de la excepción disparada. Luego, se ejecuta el bloque catch del manejador seleccionado y
la excepción se considera manejada. Solamente se ejecuta el bloque catch cuyo argumento es del mismo tipo
que el de la excepción disparada. La coincidencia entre el tipo de la excepción disparada y la de su manejador
no tiene que ser exacta: el tipo del manejador puede ser el de cualquier superclase de la excepción disparada.
¿Qué ocurre si se dispara una excepción en el bloque try?
import java.io.*;
public class EscribirNumerosEntrada {
public static void main(String[] args) {
PrintWriter out = null;
int suma = 0;
try {
out = new PrintWriter(new FileWriter("doc"));
for (int i = 0; i < args.length; i++) {
suma = +Integer.parseInt(args[i]);
}
out.write("La suma es: "+suma);
out.close();
} catch (IOException e1) {
System.err.println("Excepción de IO: " + e1.getMessage());
} catch (NumberFormatException e2) {
System.err.println("Uno de los argumento no es entero:” + e2.getMessage()); 
} 
System.err.println(“Fin de la suma y escritura”);
}}
¿Cuál es la salida si doc es una carpeta?
Excepción de IO: doc (Acceso denegado)
Fin de la suma y escritura
¿Qué ocurre si adentro del try invocamos a diferentes
métodos que disparan IOException?
Podemos usar el mismo manejador. 
Si necesitamos manejadores 
diferentes -> debemos usar más de 
un bloque catch
1
2
3
Capturar y Manejar Excepciones
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Manejadores Genéricos y Especializados
catch (FileNotFoundException e) {
.........
}
También es posible capturar un error basado en su grupo ó tipo general, especificando 
alguna de las superclases de FileNotFoundException: 
catch (IOException e) {
.........
}
Se puede averiguar la excepción específica usando el 
parámetro e. Requiere agregar código en el manejador.
Es posible establecer un manejador más general que capture cualquier tipo de excepción
catch (Exception e) {
.........
}
Los manejadores de excepciones muy generales hacen el
código propenso a errores pues capturan y manejan
excepciones que no fueron previstas y por lo tanto no se
manejan correctamente.
No son útiles para recuperación de errores.
Un manejador de excepciones específico es aquel que maneja un tipo determinado de
error. Puede hacerse un mejor manejo del error.
Capturar y Manejar Excepciones 
(try/catch)
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
public void metodo() {
PrintWriter out=null;
try{ 
out=new PrintWriter(new FileWriter("doc"));
. . .
} catch(Exception e){
System.err.println("Exception capturada");
} catch(IOException e) {
System.err.println("IOException capturada");
}
}
catch(IOException e) { 
System.err.println(“IOException capturada"); 
} catch(Exception e) { 
System.err.println(“Exception capturada");
NO!! 
NO COMPILA!!! pues se especificó un manejador inalcanzable:
Unreachable catch block for IOException. It 
is already handled by catch block for 
Exception
Está bien el código? Siempre que se especifique un manejador general 
y uno específico, primero debe especificarse el 
específico y luego el general, sino el programa 
NO compilará.
Un bloque try tiene bloques catch que capturan errores generales y específicos, importa el 
orden
Manejadores Genéricos y Especializados
Capturar y Manejar Excepciones 
(try/catch)
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
El bloque finally
Antes de que el control sea transferido a otra parte del programa, podemos definir un bloque finally que
siempre se ejecutará. Comúnmente se usa para cerrar un archivo abierto, cerrar una conexión de red, borrar
algo que hemos dibujado en la pantalla, etc.
import java.io.*;
public class EscribirNumerosEntrada {
public static void main(String[] args) {
PrintWriter out = null; int suma = 0;
try {
out = new PrintWriter(new FileWriter("doc"));
for (int i = 0; i < args.length; i++) {
suma = +Integer.parseInt(args[i]);
}
out.write("La suma es: "+suma);
out.close();
} catch (IOException e1) {
System.err.println("Excepción de IO: " + e1.getMessage());
} catch (NumberFormatException e2) {
System.err.println("Uno de los argumento no es entero:” + e2.getMessage()); 
} 
System.err.println(“Fin de la suma y escritura”);
}}
} finally {
if (out !=null){
System.out.println(“Cerrando el archivo”);
out.close();
} else System.ou.println(“El archivo no se abrió”); 
}
System.out.println(“Fin de la suma y escritura”);
}
} 
El sistema de ejecución de Java siempre ejecuta las
sentencias del bloque finally independientemente
de lo sucedido en el bloque try. Garantizamos que
out se cierre siempre:
(1) Si se dispara una IOException
(2) Si se dispara una NumberFormatExceptio o
cualquiera RunTimeExcpetion
(3) Si no hay errores
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Propagar Excepciones
 JAVA provee una sintaxis que permite informarle al programador las excepciones que podrían
disparar los métodos que usa. Si las excepciones no se manejan, JAVA fuerza a propagar o a
especificacar las excepciones.
 La Especificación de Excepciones es parte de la declaración del método y se escribe después de la
lista de argumentos. Es parte de la interface pública del método. Se usa la palabra clave throws
seguida por una lista de tipos de excepciones que podrían dispararse en el alcance del método.
 Si un método NO captura ni maneja las excepciones chequeables disparadas adentro de su
alcance, el compilador JAVA fuerza al método a propagarlas o especificarlas en su declaración.
 En algunas situaciones es mejor que un método propague las excepciones, por ejemplo si se
está implementando una librería de clases, es posible que no se puedan prever las necesidades de
todos los usuarios de la librería. En este caso, es mejor no capturar las excepciones y permitir
que los usuarios que la usan codifiquen el tratamiento de excepciones.
public void metodo() throws IOException {
PrintWriter out=null;
try{
out=new PrintWriter(new FileWriter(”salida.txt”));
. . . // se escriben datos en el archivo
} finally {
if (out!=null) out.close();
}
}
Podríamos propagar la excepción y usar el 
bloqye try/finally para asegurarnos de que 
siempre se cierre el objeto PrintWriter
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Crear excepciones propias (1/2)
Problema de conexiónpublic class ServerTimeOutException extends Exception {
private int port;
public ServerTimeOutException() {
super();
}
public ServerTimeOutException(String message) {
super(message);
}
public ServerTimeOutException(String message, int port) {
super(message);
this.port = port;
}
public int getPort() {
return port;
}
}
Las excepciones definidas por los usuarios deben ser subclases de la clase Exception para que sean
chequeables. Las clases de tipo Exception pueden contener lo que contiene cualquier clase.
El uso del método getMessage()
heredado desde la clase Exception nos
permitirá recuperar el mensaje de nuestra
excepción.
La siguiente clase es una Exception propia que será disparada cuando un servidor no responda:
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
public class Conectar {
. . .
public void conectame(String nombreServer) throws ServerTimeOutException {
boolean exito=false;
int port=80;
exito = open(nombreServer, port);
if (!exito)
throw new ServerTimeOutException(“no se pudo conectar”);
}
}
La siguiente clase Conectar dispara la excepción que acabamos de crear si no se puede conectar al
servidor que recibe por parámetro:
Para disparar la excepción que acabamos de crear se utiliza esta
sintaxis . Usamos el constructor con sólo un argumento
El método open() retorna false si 
en 5’’ no se puede conectar
Manejando métodos que disparan excepciones chequeables:
public void buscarServidor() {
try {
con.conectame(servidorDefault); 
} catch (ServerTimeOutException e) {
System.out.println("Servidor "+ e.getMessage() + " fuera deservicio");
}
}
método que dispara una 
excepción que hay que 
manejar
Crear excepciones propias (1/2)
Problema de conexión
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Crear excepciones propias (1/5)
Café Virtual
Throwable
Exception
TemperatureException
TooColdException TooHotException
Cuando se diseña un paquete de clases JAVA, éstas deben interactuar bien y sus interfaces
deben ser fáciles de entender y de usar. Para ello, es bueno diseñar clases de excepciones.
Las condiciones excepcionales que pueden ocurrir cuando el cliente toma una taza de café
son las siguientes: el café está muy frío o muy caliente.
class TemperatureException extends Exception {
}
class TooColdException extends TemperatureException{
}
class TooHotException extends TemperatureException {
}
Convención de nombres: es una buena práctica 
agregar el string “Exception” a todos los nombres 
de clases que heredan directa ó indirectamente 
de la clase Exception.
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Definimos la clase VirtualPerson que dispara excepciones en caso de que la temperatura esté por
debajo de la mínima o sea superior a la máxima.
class CoffeeCup {
// 75 grados Celsius: temperatura ideal del café
private int temperature = 75;
public void setTemperature(int val){
temperature = val;
}
public int getTemperature() {
return temperature;
}
}
class VirtualPerson {
private static final int tooCold = 65;
private static final int tooHot = 85;
public void drinkCoffee(CoffeeCup cup)
throws TooColdException, TooHotException {
int temperature = cup.getTemperature();
if (temperature <= tooCold) {
throw new TooColdException();
}
else if (temperature >= tooHot) {
throw new TooHotException();
}
}
}
Se dispara una 
excepción
Se declaran las excepciones que puede 
disparar el método drinkCoffee()
Crear excepciones propias (2/5)
Café Virtual
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
class VirtualCafe {
public static void serveCustomer(VirtualPerson cust, CoffeeCup cup) { 
try {
cust.drinkCoffee(cup);
System.out.println(”El Café está OK.");
} catch (TooColdException e) {
System.out.println(”El Café está muy frío.");
} catch (TooHotException e) {
System.out.println(”El Café está muy caliente.");
}
}
. . .
}
El método drinkCoffee puede disparar las 
excepciones: TooHotException ó 
TooColdException
catch (TemperatureException e) {
System.out.println(”El Café..);
}
Se recomienda el uso de manejadores de excepciones especializados. Los manejadores genéricos -
que agrupan muchos tipos de excepciones- no son útiles para recuperación de errores, ya que el 
manejador tiene que determinar que tipo de excepción ocurrió, para elegir la mejor estrategia para 
recuperar el error.
Las clases TooColdException y TooHotException podrían tener una variable 
de instancia con la temperatura.
Crear excepciones propias (3/5)
Café Virtual
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Crear excepciones propias (4/5)
Café Virtual
abstract class TemperatureException extends Exception {
private int temperature; 
public TemperatureException(int temperature) {
this.temperature = temperature;
}
public int getTemperature() {
return temperature;
}
}
class TooColdException extends TemperatureException {
public TooColdException(int temperature) {
super(temperature);
}
} class TooHotException extends TemperatureException {
public TooHotException(int temperature) {
super(temperature);
}
}
Agregamos información a las excepciones
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Ahora la clase VirtualPerson dispara excepciones con más información
class VirtualPerson {
private static final int tooCold = 65;
private static final int tooHot = 85;
public void drinkCoffee(CoffeeCup cup)
throws TooColdException, TooHotException {
int temperature = cup.getTemperature();
if (temperature <= tooCold) {
throw new TooColdException(temperature);
}
else if (temperature >= tooHot) {
throw new TooHotException(temperature);
}
}
}
Se dispara una 
excepción
Crear excepciones propias (5/5)
Café Virtual
Contamos con la 
temperatura exacta que 
produjo la excepción
Taller de Lenguajes II – Ingeniería en Computación – 2012 Prof. Claudia Queiruga - Prof. Laura Fava
Sobrescritura de método y Excepciones
Cuando se sobrescribe un método solamente se pueden disparar las excepciones especificadas en la
versión de la clase base del método. La utilidad de esta restricción es que el código que funciona
correctamente para un objeto de la clase base, seguirá funcionando para un objeto de la clase
derivada (principio fundamental de la OO).
La interface de especificación de excepciones de un método puede reducirse y sobrescribirse en la
herencia, pero nunca ampliarse.
public class A{
public void f() throws AException{
}
public void g() throws BException,
CException {
}
}
public class B extends A{
public void f(){
}
public void g() throws DException{
}
}
class AException extends Exception {}
class BException extends AException {}
class CException extends AException {}
class DException extends BException {}
public class Test{
public static void main(String[] args){
try { 
A x= new A();
x.f();
x.g();
} catch (BException e) {}
catch (CException e) {}
catch (AException e) {}
}
}

Otros materiales