fundamentos+de+ programación+pepe/doc/fprg/08-exception.pptx.pdf · fundamentos+de+ programación+...
TRANSCRIPT
Fundamentos de Programación
Excep5on errores en 5empo de ejecución
José A. Mañas <[email protected]> Dpto. de Ingeniería de Sistemas Telemá@cos
hCp://www.lab.dit.upm.es/~fprg/ 1.12.2009
excepciones
• una forma de reportar errores – no usan el resultado del método – informa al código cliente de lo que ha ido mal, si algo va mal
– no pasa nada si todo va bien
• la filosoSa es – mientras todo va bien, aquí no pasa nada
• se programa de buena fe: “to ’er mundo é güeno”
– si algo va mal, el servidor grita • pero hay que tener oído para detectar problemas
1.12.2009 2
14.1.2009 3
índice
1. Ejemplos: errores provocados
2. Objetos de la familia Excep@on 3. Métodos y excepciones 4. try, catch, finally 5. Arquitectura: interface & extends 6. Criterios de uso
14.1.2009 4
errores en ejecución 7 public class Errores { 8 9 public sta@c void divisionPorCero() { 10 int n = 2 / 0; 11 } 12 13 public sta@c void objetoInexistente() { 14 String s = null; 15 boolean esManuel = s.equals("Manuel"); 16 } 17 18 public sta@c void arraySinCrear() { 19 int[] vector = null; 20 int n = vector[0]; 21 } 22 23 public sta@c void arrayImposible() { 24 int[] vector = new int[-‐1]; 25 } 26 27 public sta@c void indiceDesbordado() { 28 int[] vector = new int[10]; 29 int n = vector[-‐1]; 30 }
14.1.2009 5
errores en ejecución
9 public sta@c void divisionPorCero() { 10 int n = 2 / 0; 11 }
java.lang.Arithme@cExcep@on: / by zero at Errores.divisionPorCero(Errores.java:10)
14.1.2009 6
errores en ejecución
13 public sta@c void objetoInexistente() { 14 String s = null; 15 boolean esManuel = s.equals("Manuel"); 16 }
java.lang.NullPointerExcep@on at Errores.objetoInexistente(Errores.java:16)
14.1.2009 7
errores en ejecución
18 public sta@c void arraySinCrear() { 19 int[] vector = null; 20 int n = vector[0]; 21 }
java.lang.NullPointerExcep@on at Errores.arraySinCrear(Errores.java:21)
14.1.2009 8
errores en ejecución
23 public sta@c void arrayImposible() { 24 int[] vector = new int[-‐1]; 25 }
java.lang.Nega@veArraySizeExcep@on at Errores.arrayImposible(Errores.java:25)
14.1.2009 9
errores en ejecución
27 public sta@c void indiceDesbordado() { 28 int[] vector = new int[10]; 29 int n = vector[-‐1]; 30 }
java.lang.ArrayIndexOutOfBoundsExcep@on: -‐1 at Errores.indiceDesbordado(Errores.java:30)
14.1.2009 10
índice
1. Ejemplos: errores provocados
2. Objetos de la familia Excep@on 3. Métodos y excepciones 4. try, catch, finally 5. Arquitectura: interface & extends 6. Criterios de uso
14.1.2009 11
jerarquía de excepciones
Throwable
Excep@on
Error Error Error
Run@meExcep@on
Error Error
Error Error
14.1.2009 12
jerarquía de excepciones
14.1.2009 13
9picas
• Error – CoderMalfunc@onError – ...
• Excep@on – IOExcep@on – Run@meExcep@on – otras definidas por nosotros ...
• Run@meExcep@on – Arithme@cExcep@on – ClassCastExcep@on – IllegalArgumentExcep@on – IndexOutOfBoundsExcep@on – NullPointerExcep@on – ...
14.1.2009 14
objetos Excep5on
hCp://java.sun.com/javase/6/docs/api/java/lang/[email protected]
• Constructores – Excep@on() – Excep@on(String message)
• Métodos – String toString() – String getMessage() – void printStackTrace();
14.1.2009 15
índice
1. Ejemplos: errores provocados
2. Objetos de la familia Excep@on 3. Métodos y excepciones 4. try, catch, finally 5. Arquitectura: interface & extends 6. Criterios de uso
ejercicios
• chequear el argumento de elimina(Contacto) – lanzando IllegalArgumentExcep@on – lanzando Excep@on
1.12.2009 16
public void elimina(String clave) { Contacto contacto = map.get(clave); map.remove(contacto.getNombre()); map.remove(contacto.getTelefono()); numero-‐-‐; }
ejercicios
• chequear el argumento de elimina(Contacto) – lanzando IllegalArgumentExcep@on
1.12.2009 17
public void elimina(String clave) { if (clave == null || clave.length() == 0) throw new IllegalArgumentExcep@on("clave nula"); Contacto contacto = map.get(clave); if (contacto == null) throw new IllegalArgumentExcep@on("clave inexistente"); map.remove(contacto.getNombre()); map.remove(contacto.getTelefono()); numero-‐-‐; }
ejercicios
• chequear el argumento de elimina(Contacto) – lanzando Excep@on
1.12.2009 18
public void elimina(String clave) throws Excep@on { if (clave == null || clave.length() == 0) throw new Excep@on("clave nula"); Contacto contacto = map.get(clave); if (contacto == null) throw new Excep@on("clave inexistente"); map.remove(contacto.getNombre()); map.remove(contacto.getTelefono()); numero-‐-‐; }
14.1.2009 19
métodos y excepciones
• Un método puede, en su cuerpo, lanzar una excepción
• Debe indicar en la cabecera que puede lanzar una excepción – nótese que puede lanzarla o no – es una opción, no una obligación
metodo (argumentos) throws Exception { ... throw new Exception(); ... }
ejercicios
• las excepciones se pueden propagar “pasando la pelota al siguiente”
1.12.2009 20
public void cambia(String claveAn@gua, Contacto contacto) throws Excep@on { elimina(claveAn@gua); mete(contacto); }
14.1.2009 21
obligación de declarar
• Las excepciones de clase Excep@on – deben declararse en la cabecera de los métodos que las puedan lanzar
– o ser capturadas (catch) internamente • Error
– no hay que declararlas en las cabeceras – no suelen usarse en los programas – son errores mayúsculos que de@enen el programa
• Run@meError – no hay que declararlas en las cabeceras – pueden capturarse en un catch – se usan para detectar errores de uso
14.1.2009 22
obligación de declarar
Throwable
Error Exception
RuntimeException
MyUncheckedException MiExcepcion MyUncheckedError
NOTA: aún si no hay obligación, se recomienda declarar lo que se programa
obligación
ejercicios
• chequear los argumentos del constructor – lanzando IllegalArgumentExcep@on – lanzando Excep@on
1.12.2009 23
public Contacto(String nombre, String telefono, String direccion) { // se eliminan blancos al principio o al final this.nombre = nombre.trim(); this.telefono = telefono.trim(); this.direccion = direccion.trim(); }
ejercicios
• chequear los argumentos del constructor – lanzando IllegalArgumentExcep@on
1.12.2009 24
public Contacto(String nombre, String telefono, String direccion) { if (nombre == null || nombre.length() == 0) throw new IllegalArgumentExcep@on("nombre nulo"); if (telefono == null || telefono.length() == 0) throw new IllegalArgumentExcep@on("telefono nulo"); if (direccion == null || direccion.length() == 0) throw new IllegalArgumentExcep@on("direccion nulo"); // se eliminan blancos al principio o al final this.nombre = nombre.trim(); this.telefono = telefono.trim(); this.direccion = direccion.trim(); }
ejercicios
• chequear los argumentos del constructor – lanzando Excep@on
1.12.2009 25
public Contacto(String nombre, String telefono, String direccion) throws Excep@on { if (nombre == null || nombre.length() == 0) throw new Excep@on("nombre nulo"); if (telefono == null || telefono.length() == 0) throw new Excep@on("telefono nulo"); if (direccion == null || direccion.length() == 0) throw new Excep@on("direccion nulo"); // se eliminan blancos al principio o al final ... }
excepción propia
• recurre a los constructores de super
1.12.2009 26
public class MiExcepcion extends Excep@on { public MiExcepcion() { }
public MiExcepcion(String mensaje) { super(mensaje); } }
ejercicios
• chequear los argumentos del constructor – lanzando MiExcepcion
1.12.2009 27
public Contacto(String nombre, String telefono, String direccion) throws MiExcep@on { if (nombre == null || nombre.length() == 0) throw new MiExcepcion("nombre nulo"); if (telefono == null || telefono.length() == 0) throw new MiExcepcion("telefono nulo"); if (direccion == null || direccion.length() == 0) throw new MiExcepcion("direccion nulo"); // se eliminan blancos al principio o al final ... }
excepción propia
• recurre a los constructores de super
1.12.2009 28
public class MiExcepcion extends Excep@on { private int codigo;
public MiExcepcion(int codigo) { this.codigo = codigo; } public MiExcepcion(int codigo, String mensaje) { super(mensaje); this.codigo = codigo; } public int getCodigo() { return codigo; } }
14.1.2009 29
índice
1. Ejemplos: errores provocados
2. Objetos de la familia Excep@on 3. Métodos y excepciones 4. try, catch, finally 5. Arquitectura: interface & extends 6. Criterios de uso
14.1.2009 30
¿a dónde van las excepciones lanzadas?
• Su lanzamiento interrumpe la ejecución secuencial
• Se propagan hasta que son capturadas – interrumpe toda sentencia que no la capture
• Se capturan con un catch – se pueden atrapar al vuelo
• try { ... } catch (Exception e) { System.err.println(e); }
14.1.2009 31
try {...} catch (args) {...}
• Si no se lanza nada, el catch como si no exis@era
• Dentro del try se lanza (throw) una excepción – Se olvida el resto del código – Se ejecuta lo que diga el catch
try {
... throw new Excep@on();
...
} catch (Excep@on e) {
}
¿qué hacer con la pelota?
• o se pasa ... o se atrapa • lo que no puede hacerse es ignorarla
1.12.2009 32
public void ac@onPerformed(Ac@onEvent ev) { agenda.mete(new Contacto(nameField.getText(), phoneField.getText(), address.getText())); }
¿qué hacer con la pelota?
• puede no hacer nada
1.12.2009 33
public void ac@onPerformed(Ac@onEvent ev) { try { agenda.mete(new Contacto(nameField.getText(), phoneField.getText(), address.getText())); } catch (Excep@on e) { // no hago nada } }
¿qué hacer con la pelota?
• o mejor se lo comenta al usuario
1.12.2009 34
public void ac@onPerformed(Ac@onEvent ev) { try { agenda.mete(new Contacto(nameField.getText(), phoneField.getText(), address.getText())); } catch (Excep@on e) { [email protected](GUI.this, e.getMessage()); } }
14.1.2009 35
métodos y excepciones
método_3() throws Excep@on { throw new Excep@on(); }
método_2() throws Excep@on { método_3(); }
método_1() { try { método_2(); } catch (Excep@on e) { e...; } }
main(...) { método_1(); } traza: llam
ada al m
étod
o
14.1.2009 36
métodos y excepciones
método_3() throws Excep@on { throw new Excep@on(); }
método_2() throws Excep@on { método_3(); }
método_1() { try { método_2(); } catch (Excep@on e) { e...; } }
main(...) { método_1(); } trasiego de la excep
ción
14.1.2009 37 / 40
java.lang.Exception at Errores.método_3(Errores.java:34) at Errores.método_2(Errores.java:38) at Errores.método_1(Errores.java:43) at Errores.método_0(Errores.java:50)
14.1.2009 38
catch
try { ... ... ... } catch (claseA ida) { ... ... ... } catch (claseB idb) { ... ... ... } catch (classC idc) { ... ... ...
• Los diferentes catch se intentan en el orden en que aparecen hasta que uno de ellos casa; después de casar con uno, los demás se olvidan
• Casar significa que la excepción a agarrar es de la clase indicada o de una clase extensión de ella (sub@po de ...) – ida instanceof claseA – idb instanceof claseB – idc instanceof claseC
14.1.2009 39
try ... catch ... finally
• Se puede añadir un trozo finally que se ejecuta – bien cuando acaba el código normal (try) – bien cuando acaba el código excepcional (catch) – ... es decir, SIEMPRE se ejecuta;
incluso si try lanza una excepción que no captura ningún catch
14.1.2009 40
finally
try { ... ... ... throw new Excep@on(); ... ... ... } catch (Excep@on e) { ... ... ... } finally { ... ... ... }
try { ... ... ... throw new Excep@on(); ... ... ... } catch (Excep@on e) { ... ... ... } finally { ... ... ... }
14.1.2009 41
ejemplo public class Inversos { public sta@c void main(String[] args) { Scanner scanner = new Scanner(System.in); int pruebas = 0; while (true) { double inverso = 0; try { String x = scanner.next(); if (x.equals("fin")) break; int valor = Integer.parseInt(x); inverso = 100 / valor; } catch (Excep@on e) { System.out.println(" -‐> " + e); inverso = 0; } finally { pruebas++; System.out.println(" -‐> " + pruebas + ": " + inverso); } } } }
14.1.2009 42
índice
1. Ejemplos: errores provocados
2. Objetos de la familia Excep@on 3. Métodos y excepciones 4. try, catch, finally 5. Arquitectura: interface & extends 6. Criterios de uso
14.1.2009 43
excep5on & interface
• Si en la interface NO se permiten – la implementación NO puede permi@rlas
• Si en la interface SÍ se permiten – la implementación puede permi@rlas
– o no
14.1.2009 44
ejemplo
interface Funcion { double y(double x) throws Excep@on; }
class Coseno implements Funcion { double y(double x) { return Math.cos(x); } }
class Tangente implements Funcion { double y(double x) throws Excep@on { double seno= Math.sin(x); double coseno= Math.cos(x); if (Math.abs(coseno) < 1e-‐6) throw new Excep@on(); return seno/coseno; } }
class Seno implements Funcion { double y(double x) { return Math.sin(x); } }
14.1.2009 45
ejemplo double raiz(Funcion f, double m, double n) throws Excep@on { double p = (m + n) / 2; if (Math.abs(f.y(p)) < ERROR) return p; if (Math.abs(m -‐ n) < ERROR) throw new MiEx("no hay solución"); if (f.y(m) * f.y(p) > 0) return raiz(f, p, n); else return raiz(f, m, p); }
public sta@c void main(String[] args) throws Excep@on { // nadie captura la excepción long t0 = System.currentTimeMillis(); try { Funcion f = new Test(); System.out.println("raíz= " + raiz(f, 1, 3)); } finally { long t2 = System.currentTimeMillis(); System.out.println((t2 -‐ t0) + "ms"); } }
14.1.2009 46
excep5on & extends
• La subclase puede redefinir – métodos de objetos – a base de definir métodos con la misma signatura
• mismo nombre
• mismo número y @po de argumentos
• igual o menos excepciones • igual o más visible
– (paquete) → public
• igual resultado
signatura
14.1.2009 47
índice
1. Ejemplos: errores provocados
2. Objetos de la familia Excep@on 3. Métodos y excepciones 4. try, catch, finally 5. Arquitectura: interface & extends 6. Criterios de uso
14.1.2009 48
excepciones
• Las excepciones ofrecen salidas de emergencia – de { sentencias; } – de llamadas a métodos
• Se pretende que el programador se centre en el comportamiento “normal” (si todo va bien) – y que la situación excepcional aborte – informando de dónde y por qué
14.1.2009 49
¿cuándo usar excepciones?
• Conviene usarlo cuando hay que programar una situación anómala – el que lo lea se pondrá en situación mental de analizar una situación excepcional
14.1.2009 50
¿cuándo extender?
• Programa mejor documentado
• Crear hijos para poder discriminar en el catch
14.1.2009 51
¿cuando lanzar Excep5on?
• Un método lanzará una Excep@on, que queda documentada en la cabecera, cuando – la responsabilidad de determinar si el método falla es del propio método, que informa cuando lo detecta
– es responsabilidad del que llama ges@onar la excepción cuando se produzca
– son errores RECUPERABLES
PROGRAMACIÓN INFORMATIVA
14.1.2009 52
¿... Run5meExcep5on?
• Un método lanzará una Run@meExcep@on, incluso NO documentada en la cabecera, cuando – es responsabilidad del que llama al método, saber si los argumentos son correctos o darían pie a un error
– el que llama no prevé ninguna excepción, ni tratamiento explícito alguno
– el llamado se protege de fallos del programador lanzando una excepción de ejecución
– son errores IRRECUPERABLES
PROGRAMACIÓN DEFENSIVA
14.1.2009 53
índice
1. Ejemplos: errores provocados
2. Objetos de la familia Excep@on 3. Métodos y excepciones 4. try, catch, finally 5. Arquitectura: interface & extends 6. Criterios de uso
ejercicio 1
• crear un método que lanza una Excep5on dentro de un bloque try, pasándole un texto
• capture la Excep5on e imprima el mensaje
• añada un finally e imprima un mensaje para demostrar que se ha ejecutado
1.12.2009 54
ejercicio 2
• cree una excepción propia derivada de Excep5on, pasándole un texto
• escriba un bloque try que lance la excepción, la capture e imprima el texto
1.12.2009 55
ejercicio 3
• usando un método que lee un número – double leeNumero()
• y una función que puede – double f(double n) throws Excep@on
• escriba un bucle que lee números y se los pasa a f(n) hasta que no se lanza una excepción
1.12.2009 56
ejercicio
• escriba una excepción ME1 propia que deriva de Excep@on
• escriba una excepción ME2 propia que deriva de ME1
• escriba un bloque try que captura de forma diferenciada – NullPointerExcep@on – otras Run@meExcep@on – ME1 y ME2
– otras Excep@on
1.12.2009 57
ejercicio
• cree una excepción no chequeada que admita en su constructor otra excepción para ocultarla – constructor: Envoltorio(Excepcion e) – geCer: Excep@on getExcep@on()
• úsela para 1. envolver una excepción, 2. sacarla sin chequear 3. resucitarla más tarde, cuando interese
1.12.2009 58