480 likes | 708 Views
Control de excepciones. El término excepción puede definirse de la siguiente forma: Una excepción es un evento que ocurre durante la ejecución del programa que interrumpe el flujo normal de las sentencias. 1. Se produce la excepción.
E N D
El término excepción puede definirse de la siguiente forma: Una excepción es un evento que ocurre durante la ejecución del programa que interrumpe el flujo normal de las sentencias. 1. Se produce la excepción. 2. Se crea un objeto que representa la excepción. 3. Se envía al método que ha provocado la excepción. 4. El método tiene dos opciones: I. Gestiona la excepción II. Pasa la excepción al método que lo llamó. Es obligatorio que la excepción sea capturada y procesada en algún punto. CONTROL DE EXCEPCIONES
Las excepciones pueden ser: Generadas por el intérprete: • Errores fundamentales que violan las reglas del lenguaje o las restricciones del entorno. Generadas por el código (manuales): Informan de una condición de error. • Se gestionan con cinco palabras clave: < try: Bloque que incluye las sentencias que se quieren controlar. < catch: Captura la excepción para poder tratarla. < throw: Genera una excepción manualmente. < throws: Lanza la excepción fuera del método. < finally: Bloque que incluye código a ejecutar antes de que termine un método.
Toda excepción debe ser instancia de la súper clase Throwablede la cual se derivan las clases: Error y Exeption. La siguiente figura muestra parcialmente la jerarquía de las clases relacionadas con Throwble. Toda excepción debe ser instancia de la super clase Throwablede la cual se derivan las clases: Error y Exeption. La siguiente figura muestra parcialmente la jerarquía de las clases relacionadas con Throwble. Excepciones estándar de Java
• Throwable (String mensaje); Constructor. La cadena es opcional . • ThrowablefillInStackTrace(); Llena la pila de traza de ejecución. • StringgetLocalizedMessage(); Crea una descripción local de este objeto. • StringgetMessage(); Devuelve la cadena de error del objeto. • voidprintStackTrace (PrintStream_o_PrintWriters); Imprime este objeto y su traza en el flujo del parámetro, o en la salida estándar (por defecto). • StringtoString; Devuelve una breve descripción del objeto. Métodos de Throwable
Esta clase esta relacionada con errores de compilación, del sistema o de la maquina virtual de java (JVM). •No deben ser lanzados por las clases de usuario. • Estas excepciones rara vez ocurren y cuando así sea lo único que se puede hacer es intentar cerrar el programa sin perder los datos. • Ejemplos: OutOfMemoryError; StackOverflow; etc. ERROR
Los programas en Java trabajarán con las excepciones de la rama Exception. Este grupo se divide a su vez en: • Las clases que derivan directamente de Exception (explícitas) • Las que derivan de RuntimeException (implícitas) Se utilizan las RunTimeException para indicar un error de programación. Si se produce una excepción de este tipo hay que arreglar el código. • Un cast incorrecto • Acceso a un array fuera de rango • Uso de un puntero null El resto de las Exception indican que ha ocurrido algún error debido a alguna causa ajena al programa. • Un error de E/S • Error de conexión EXEPTION
1 importjava.math.BigInteger; 3 publicclassMain { 5 privatestaticvoidusage(){ 6 System.out.println("USAGE: java Main number1 number2"); 7 } 9 privatestaticvoid divide(String a, String b){ 10 try { 11 BigInteger bi1 = new BigInteger(a); //Si el primer parametro no es un número, el programa lanzará una // excepción de tipo NumberFormatException 12 BigInteger bi2 = new BigInteger(b); //no se ejecutara 13 System.out.println( bi1.divide(bi2) ); //no se ejecutara 14 } catch (NumberFormatException e2) { //Aquí será capturada NumberFormatException 15 System.err.println("Not a number! " + e2.getMessage()); //se reanuda la ejecucion 16 usage(); 17 } 18 } 20 publicstaticvoidmain(String[] args) { 21 divide(args[0],args[1]); 22 } Si el segundo parametro es un cero, se producirá una excepción de tipo ArithmeticException que no hemos contemplado en nuestro programa, y la ejecución terminará
LANZAMIENTO DE UNA EXCEPCIÓN • Cuando en un método se produce una situación anómala es necesario lanzar una excepción.
Lanzamiento de una excepciónEXCEPTION • Para lanzar una excepción se requiere de lo siguiente: • 1.- Se crea el objeto exception de la clase adecuada • 2.- Se lanza la excepción con la sentencia throw seguida del objeto exception creado • Esta excepción debe ser capturada (cath) y gestionada en el propio método o en algún otro lugar del programa (en otro método anterior en la pila o stack de llamadas)
Para la creación de una excepción (exception) ocupamos try, catch, finally y también throw. • Try lo utilizamos para indicarle a Java que intente realizar la excepción contenida en esta sección. • Catch se utiliza para indicar a Java que realice lo que se indica en este parte del código si es que no se cumple o no se puede realizar lo contenido en try • Finally consiste en liberar conexiones hacia bases de datos que pudieran haber sido asignadas en la sección try esta función siempre se realizara.
Ejemplo clásico … public void transferir (String IDorigen, String IDdestino, int cantidad) { Cuenta origen; Cuenta destino; // Comenzar transacción database.startTransaction(); try { origen = database.find(IDorigen); if (origen == null) throw new Exception("No existe ” + IDorigen); origen.setBalance (origen.getBalance() – cantidad); database.store(origen); destino = database.find(IDdestino); if (destino == null) throw new Exception("No existe ” + IDdestino); destino.setBalance(destino.getBalance()+cantidad); database.store(destino) // Confirmar la transacción database.commit(); } catch (Exception error) { // Cancelar la transacción database.rollback(); } } …
Public static void metodo x () { try { int x=interger.parseInt (“3”); System.out.println (“valor de x: “+x); } catch (exception E) { E.printStackTrace(); //(esto se puede modificar para que no nos muestre en pantalla todo el error) queda de la forma siguiente: System.out.println (“Se produjo un error”) } }
En lenguajes de programación como Java, un uso típico de la secuencia try ... catch es el acceso a ficheros o recursos que no se sabe si estarán disponibles. Si el recurso no está disponible se producirá una excepción, la cual puede ser capturada para evitar la terminación abrupta del programa, y mostrar en su lugar un mensaje de error o de revisión de los datos introducidos por el usuario (por poner un ejemplo). Otra aplicación de la captura de errores está en la comprobación de líneas de código que podrían contener errores. Para usuarios nóveles puede ser de gran ayuda. Capturar una exception
Con la captura de errores podemos añadir bloques de código encaminados a gestionar las posibles condiciones de error que puedan surgir durante la ejecución de un script. En caso de que no tengamos claro si cierta codificación es correcta, podemos evaluar su ejecución y mostrar los mensajes de error que dicha codificicación nos produce. Sin duda, una herramienta de programación eficaz y ya al alcance de todos.
El Bloque Try • El primer paso en la construcción de un manejador de excepciones es encerrar las sentencias que podrían lanzar una excepción dentro de un bloque try. En general, este bloque se parece a esto. try { //sentencias Java } El segmento de código etiquetado sentencias java está compuesto por una o más sentencias legales de Java que podrían lanzar una excepción.
Ejemplo void metodo1() { … try{ //codigo que puede lanzarlas excepciones IOException y MyException} Catch(IOException e1) {//Se ocupa de IOException simplemente dando aviso System.out.println(e1.getmessage()); }catch (MyException e2) { //Se ocupa de MyExceptiondadndo un aviso y finalizando la funcion Sytem.out.println(e2.getmessage()); return; } //Fin del metodo1
Se dice que el bloque trygobierna las sentencias encerradas dentro del él y define el ámbito de cualquier manejador de excepción (establecido por su subsecuente bloque catch) asociado con él. En otras palabras, si ocurre una excepción dentro del bloque try, esta excepción será manejada por el manejador de excepción asociado con esta sentencia try. Una sentencia try debe ir acompañada de al menos un bloque catch o un bloque finally.
El Bloque Catch Es el código que se ejecuta cuando se produce la excepción. No puede haber ningún código entre el final de la sentencia try y el principio de la primera sentencia catch. La forma general de una sentencia catch en Java es esta. catch (AlgunObjetoThrowablenombreVariable) { // Sentencias Java }
El bloque catch contiene una serie de sentencias Java legales. Estas sentencias se ejecutan cuando se llama al manejador de excepción. El sistema de ejecución llama al manejador de excepción cuando el manejador es el primero en la pila de llamadas cuyo tipo coincide con el de la excepción lanzada.
Se pueden colocar sentencias catch sucesivas, cada una controlando una excepción diferente. No debería intentarse capturar todas las excepciones con una sola cláusula. • Esto representaría un uso demasiado general, podrían llegar muchas más excepciones de las esperadas. En este caso es mejor dejar que la excepción se propague hacia arriba y dar un mensaje de error al usuario
Relanzar una exception • Existe algunos casos en los cuales el código de un método puede generar una Exception y no se desea incluir en dicho método la gestión del error. Java permite que este método pase o relance (throws) la Exception al método desde el que ha sido llamado, sin incluir en el método los bucles try/catch correspondientes. Esto se consigue mediante la adición de throws mas el nombre de la Exception concreta después de la lista de argumentos del método. A su vez el método superior deberá incluir los bloques try/catch o volver a pasar la Exception. De esta forma se puede ir pasando la Exceptionde un método a otro hasta llegar al ultimo método del programa, el método main()
Bloque Finally • Es el bloque de código que se ejecuta siempre, haya o no excepción. Hay una cierta controversia entre su utilidad, pero, por ejemplo, podría servir para hacer un log o un seguimiento de lo que está pasando, porque como se ejecuta siempre puede dejarnos grabado si se producen excepciones y nos hemos recuperado de ellas o no.
El bloque finally debe ir detrás de todos los bloques catch considerados. Si se incluye ( ya que es opcional) sus sentencias se ejecutan siempre, sea cual sea el tipo de exception que produzca o incluso si no se produce ninguna. • El bloque finally se ejecuta incluso si dentro de los bloques try/catch hay una sentencia continue, break o return
Este bloque finally puede ser útil cuando no hay ninguna excepción. Es un trozo de código que se ejecuta independientemente de lo que se haga en el bloque try. • Cuando vamos a tratar una excepción, se nos plantea el problema de qué acciones vamos a tomar. En la mayoría de los casos, bastará con presentar una indicación de error al usuario y un mensaje avisándolo de que se ha producido un error y que decida si quiere o no continuar con la ejecución del programa.
Conclusión • Con la captura de errores podemos añadir bloques de código encaminados a gestionar las posibles condiciones de error que puedan surgir durante la ejecución de un script. En caso de que no tengamos claro si cierta codificación es correcta, podemos evaluar su ejecución y mostrar los mensajes de error que dicha codificicación nos produce. Sin duda, una herramienta de programación eficaz y ya al alcance de todos.
CREAR NUEVAS EXCEPCIONES El programador puede crear sus propias excepciones sólo con heredar de la clase EXCEPTION o de una de sus clases derivadas. Lo lógico es heredad de la clase de la jerarquía de JAVA que mejor se adapte al tipo de excepciones.
CREAR NUEVAS EXCEPCIONES Las clases EXCEPTION suelen tener dos constructores: 1.-Un constructor sin argumentos 2.-Un constructor que recibe un Stringcomo argumento.
CREAR NUEVAS EXCEPCIONES CONSTRUCTOR CON ARGUMENTO En este String se suele definir un mensaje que explica el tipo de excepción generada.
CREAR NUEVAS EXCEPCIONES Al ser clases como cualquier otra se podrían incluir variables y métodos nuevos. Conviene que este constructor llame al constructor de la clase de la que deriva super(String).
CREAR NUEVAS EXCEPCIONES classMiExceptionextendsException { publicMiException() { //Constructor por defecto super(); } publicMiException(String s) { Super(s); //Constructor con mensaje } }
-Excepción: suceso en tiempo de ejecución que puede hacer que una rutina fracase.-Fracaso: imposibilidad de conseguir el efecto para el que ha sido diseñada.-Tratamiento de la excepción: restaurar un estado en el que la rutina pueda seguir su ejecución.--Tratamiento: asumir el fracaso e informar a la rutina que ha llamado. INTRODUCCION
Ejemplo: int dividendo, divisor,cociente; // por aquí se les da valores a dividendo y divisor .... try { cociente = dividendo/divisor; } catch (ArithmeticException e) { System.out.println("Error: Division por 0"); cociente = 0; } // en cualquier caso el programa continúa por aquí ..... En otros lenguajes (y en Java, si se quiere) se utiliza la sentencia if para esto mismo: int dividendo, divisor,cociente; // por aquí se les da valores a dividendo y divisor divisor = 0; dividendo = 6; if (divisor != 0) cociente = dividendo/divisor; else { System.out.println("Error: Division por 0"); cociente = 0; } // el programa continúa por aquí ..... El uso de excepciones permite manejar los errores de forma más flexible y precisa. Además, el uso de if no resuelve todas las situaciones. La utilización de excepciones es el mecanismo utilizado por Java (y C++) para tratar situaciones inesperadas que pueden ocurrir durante la ejecución de programa: errores en la apertura de ficheros, divisiones por 0, etc.
Tipos de Excepciones • Excepciones predefinidas en el lenguaje de programación • No hace falta definirlas (están ya definidas) • El sistema las activa automáticamente • También pueden ser activadas por el programador • El programador se ocupa de su gestión • Excepciones definidas por el programador • Son las excepciones que define, activa y gestiona el programador
Tratamiento de excepciones • El tratamiento de una (posible) excepción sigue la sintaxis siguiente: • try { ... // código que puede generar una excepción } catch (TipoExcepción variable) { // código para tratar la excepción } • La variable sólo es visible en el bloque catch y se suele utilizar (aunque no siempre) para conocer información más concreta acerca de la situación excepcional que ha ocurrido.
Importante: Si un trozo de código puede generar una excepción que no se captura en un catch el método en el que está incluido debe indicar que puede lanzar dicha excepción, para que sea tratada en un bloque más externo mediante una declaración throws. La idea es que la excepción provocada dentro del código try se captura dentro del bloque catch. Las sentencias try pueden anidarse: try { bloque1 // código que puede generar una excepción try { bloque2 } catch (TipoExcepción1 variable1) { bloque3 } bloque4 } catch (TipoExcepción2 variable2) { // código para tratar la excepción } En el segundo catch se pueden tratar excepciones: • Generadas en bloque1 del tipo TipoExcepción2. • Generadas en bloque2 del tipo TipoExcepción2 pero que no son del tipo TipoExcepción1. • Generadas en bloque3 del tipo TipoExcepción2. En el primer catch sólo se podrán tratar excepciones generadas en bloque1 del tipo TipoExcepción1 .
Importante: Si un trozo de código puede generar una excepción que no se captura en un catch el método en el que está incluido debe indicar que puede lanzar dicha excepción, para que sea tratada en un bloque más Externo mediante una declaración throws. • Ejemplo: • static String quieroGalleta(String s) • throws NullPointerException{ • if (s.equals("Galleta")) • return "Gracias!"; • else • return("Quiero una galleta!!!"); • } • Sin embargo lo más habitual es tratar la excepción en el mismo sitio donde se produce:
Ejemplo: static String quieroGalleta(String s){ String resultado = ""; try { if (s.equals("Galleta")) resultado = "Gracias!"; else resultado = "Quiero una galleta!!!"; } catch (NullPointerException e) { System.out.println("argumento sin inicializar"); } return resultado; } O bien no tratarlo en absoluto: static String quieroGalleta(String s){ if (s.equals("Galleta")) return "Gracias!"; else return("Quiero una galleta!!!"); }
En este caso si se produce la excepción el programa se "romperá" y Java mostrará por pantalla la secuencia de llamadas que ha producido la excepción: Exception in thread "main" java.lang.NullPointerException at Principal.quieroGalleta(Principal.java:24) at Principal.main(Principal.java:19) Información: Sólo es obligatorio tratar (o declarar con throws las excepciones que tienen que ver con las operaciones de entrada/salida. Nosotros también podemos "lanzar" nuestras propias excepciones:
Ejemplo: public class Principal { public static void main(String[] args) { String s="tarta"; System.out.println(quieroGalleta(s)); } static String quieroGalleta(String s) throws IllegalArgumentException { if (s.equals("Galleta")) return "Gracias!"; else throw new IllegalArgumentException("Quiero una galleta!!!"); } } Como no lo hemos tratado el sistema da el error: Exception in thread "main" java.lang.IllegalArgumentException: Quiero una galleta!!! at Principal.quieroGalleta(Principal.java:15) at Principal.main(Principal.java:6) También se pueden crear nuevos tipos de excepciones, haciendo clases que hereden de la clase Exception.
La clase Exception La clase Exception es la clase de la que heredan todas las excepciones. Sólo tiene dos constructoras: • La constructora por defecto. • La constructora a la que se le pasa un String: el • mensaje de error que se mostrará. Los dos métodos principales son: • StringgetMessage(): Devuelve el mensaje • relativo al error • printStackTrace(): muestra por pantalla el mensaje • de error, junto con el número de línea • en el que se ha producido y la secuencia de llamadas • (muy útil para depurar).
La jerarquía de excepciones es: java.lang.Exception // la madre de todas las excepciones. java.lang.InterruptedException // forzosamente deben estar dentro de un try. java.lang.RunTimeException // no necesitan incluirse en un try.java.lang.ArithmeticException // por ejemplo una división por 0. java.lang.ArrayStoreException // intento de introducir un valor de tipo incorrecto en una matriz.java.lang.IllegalArgumentException // parámetro no válido.java.lang.IllegalThreadStateException // la hebra no está en un estado adecuado.java.lang.NumberFormatException // p.ej. a convertir un String en entero.java.lang.IndexOutofBoundsException // acceso a una posición no válida.java.lang.ArrayIndexOutofBoundsException // en un array.java.lang.StringIndexOutofBoundsException // en un String.java.lang.NegativeArraySizeException // intento de dar tamaño negativo a una matriz.java.lang.NullPointerException // referencia a objeto sin inicializar (tiene null como valor).java.io.IOException // forzosamente deben estar dentro de un try.java.io.EOFException // se ha intentado leer (o moverse) más allá del fin de fichero.java.io.FileNotFoundException // intento de acceder a un fichero inexistente.java.io.InterruptedIOException // por ejemplo si se saca el diskette mientras está leyendo.java.net.MalformedURLException // URL mal construida.