Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
Ferreiras JAVA, Exceptions 1 MANEJO DE EXCEPCIONES V7.0 Abril 2014 Ferreiras Ferreiras JAVA, Exceptions 2 EXPLORACION DEL TEMA Ferreiras JAVA, Exceptions 3 /* Excepcion0.java jdk1.6.0_22 Ferreiras / JAVA / Exceptions */ Ferreiras JAVA, Exceptions 4 class DivisionPorCero { private int numerador = 333; private int denominador = 0; DivisionPorCero( ) { System.out.println("\n\t=> Cociente = " + numerador / denominador ); System.out.println("\n\t=> Esta sentencia nunca se ejecutara !! " ); } DivisionPorCero( int num, int div ) { numerador = num; denominador = div; System.out.println("\n\t=> Cociente = " + numerador / denominador ); System.out.println("\n\t=> Ahora, esta sentencia si es ejecutada\n " ); } } Ferreiras JAVA, Exceptions 5 public class Excepcion0 { public static void main( String [ ] args ) { new DivisionPorCero( 333, 10 ); new DivisionPorCero(); } } Ferreiras JAVA, Exceptions 6 /* C:\Program Files\Java\jdk1.6.0_22\bin> java Excepcion0 => Cociente = 33 => Ahora, esta sentencia si es ejecutada Exception in thread "main" java.lang.ArithmeticException: / by zero at DivisionPorCero.<init>(Excepcion0.java:17) at Excepcion0.main(Excepcion0.java:39) C:\Program Files\Java\jdk1.6.0_22\bin> */ Este es un mecanismo implícito de manejo de excepciones usado por JAVA. Excepción no capturada ni manejada No se preocupe, mas adelante lo explicaremos con detalles. Ferreiras JAVA, Exceptions 7 /* Excepcion0b.java jdk1.6.0_22 Ferreiras / JAVA / Exceptions Excepción de división por cero con números reales */ Es el mismo código anterior del Excepcion0.java pero las variables de instancias son ahora todas tipo double Ferreiras JAVA, Exceptions 8 /* C:\Program Files\Java\jdk1.6.0_22\bin> java Excepcion0b => Cociente = 33.333 => Ahora, esta sentencia si es ejecutada => Cociente = Infinity => En division real por cero Esta sentencia se ejecutara !! C:\Program Files\Java\jdk1.6.0_22\bin> */ Infinity "Infinity" is produced if a floating point operation creates such a large floating-point number that it cannot be represented normally. "Infinity" is a special value that represent the concept of positive infinity. 1.0 / 0.0 -> Infinity See here: http://www.concentric.net/~ttwang/tech/javafloat.htm Ferreiras JAVA, Exceptions 9 /* Excepcion3.java jdk1.6.0_22 Ferreiras / JAVA / Exceptions / Excepciones "unchecked" Las excepciones "unchecked" no tienen que ser tiradas con un throw. Son excepciones built-in dentro de la JVM que las tiras cuando son generadas. Por ejemmplo NumberFormatException es una de estas. En este ejemplo se escribe un codigo java incorrecto a proposito para generar la excepcion NumberFormatException y que sea tirada por la JVM. */ Mas adelante veremos esto con todos los detalles pertinentes. Ferreiras JAVA, Exceptions 10 class ConvertirUnStringAnumeroDouble { ConvertirUnStringAnumeroDouble( ) { String cadena = "Ciento Cincuenta pesos con 33/100 "; double numero = Double.parseDouble(cadena); // Esta linea de código nunca se ejecutará System.out.println("\n\t=> La cadena " + cadena + " convertida es " + numero + "\n"); } } public class Excepcion3 { public static void main(String[] args) { new ConvertirUnStringAnumeroDouble(); } } Ferreiras JAVA, Exceptions 11 /* C:\Archivos de programa\Java\jdk1.6.0_25\bin> javac Excepcion3.java C:\Archivos de programa\Java\jdk1.6.0_25\bin> java Excepcion3 Exception in thread "main" java.lang.NumberFormatException: For input string: "Ciento Cincuenta pesos con 33/100" at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222) at java.lang.Double.parseDouble(Double.java:510) at ConvertirUnStringAnumeroDouble.<init>(Excepcion3.java:60) at Excepcion3.main(Excepcion3.java:72) */ No se preocupe, mas adelante lo explicaremos con detalles. Excepción no capturada ni manejada Ferreiras JAVA, Exceptions 12 COMENTARIOS: Si un programa no maneja la excepción, terminará de manera anormal cuando ésta sea generada por la JVM y mostrará un mensaje que describe cuál excepción ocurrió y dónde esta fue producida. La información asociada a una excepción es útil en la búsqueda de la causa de un problema. En los ejemplos mostrados no hay código para manejar las excepciones de manera explícita. Ferreiras JAVA, Exceptions 13 Veamos ahora: ¿Qué pasa cuando manejamos las exepciones ? Ferreiras JAVA, Exceptions 14 /* Excepcion3a.java jdk1.6.0_22 Ferreiras / JAVA / Exceptions / Excepciones "unchecked" capturadas Las excepciones "unchecked" no tienen que ser tiradas con un throw. Son excepciones built-in dentro de la JVM que las tira cuando son generadas. En este ejemplo son capturadas con catch Por ejemmplo NumberFormatException es una de estas. En este ejemplo se escribe un codigo java incorrecto a proposito para generar la excepcion NumberFormatException y que sea tirada por la JVM, pero es capturada por un catch. */ Ferreiras JAVA, Exceptions 15 class ConvertirUnStringAnumeroDouble { ConvertirUnStringAnumeroDouble( ) { try { String cadena = "Ciento Cincuenta pesos con 33/100 "; double numero = Double.parseDouble(cadena); // Esta linea de codigo nunca se ejecutara System.out.println("\n\t=> La cadena " + cadena + " convertida es " + numero + "\n"); } catch ( NumberFormatException unaExcepcion ) { System.out.println( "\n\t=> Zoquete(@) : Verifique su codigo !!\n "); } } } Ver mas adelante una lista de excepciones built-in Observe que hay dos palabras reservadas nueva: try y catch Este objeto unaExcepcion podría ser usado para acceder a metodos de su clase base. Ferreiras JAVA, Exceptions 16 public class Excepcion3a { public static void main(String[] args) { new ConvertirUnStringAnumeroDouble(); } } /* C:\Archivos de programa\Java\jdk1.6.0_25\bin> java Excepcion3a => Zoquete(@) : Verifique su codigo !! C:\Archivos de programa\Java\jdk1.6.0_25\bin> */ La excepción generada fue capturada Ferreiras JAVA, Exceptions 17 FIN DE LA EXPLORACION DEL TEMA Ferreiras JAVA, Exceptions 18 ¿Qué es una excepción1? 1: En el contexto de la ejecución de un programa computacional Es un evento que se produce durante la ejecución de un programa, interrumpiendo el flujo normal de las instrucciones . Ejemplo de eventos que producen excepciones, como vimos en la exploración del tema, son división por cero, intentar acceder a un índice inexistente de un arreglo, etc. En Java, una excepción es un objeto que contiene: Información del tipo de evento que produjo la excepción. El estado del programa cuando ocurrió el error Y, opcionalmente, información personalizada Un objeto excepción se puede tirar y ser capturado. Ferreiras JAVA, Exceptions 19 ¿Qué es una excepción1? 1: En el contexto de la ejecución de un programa computacional Las excepciones son usadas para indicar diferentes tipos de condiciones de problemas: OutOfMemoryError StackOverflowError LinkageError System errors: FileNotFoundException IOException SocketTimeoutException NullPointerException ArrayIndexOutOfBoundsException ArithmeticException … Ferreiras JAVA, Exceptions 20 ¿Qué es una excepción1? 1: En el contexto de la ejecución de un programa computacionalTodas las excepciones extends una clase base común : java.lang.Throwable. Únicamente objetos throwable pueden ser tirados y capturados ( thrown and caught ). Otras clases que tienen un significado especial en Java son: java.lang.Error, java.lang.Exception, java.lang.RountimeException Mas adelante volvemos con estos tres últimos. Ferreiras JAVA, Exceptions 21 ¿Qué es una excepción1? 1: En el contexto de la ejecución de un programa computacional Una condición de problema, desfavorable para un programa continuar su ejecución. El problema es un asunto o situación considerada indeseable o perjudicial y que necesita ser tratado y superado. Un acontecimiento que se produce durante la ejecución de un programa, interrumpiendo su flujo normal de instrucciones. Ferreiras JAVA, Exceptions 22 ¿Qué es una excepción1? 1: En el contexto de la ejecución de un programa computacional En el momento en que se produce un problema , se crea un objeto de excepción, la cual es tirada y luego manejada. El problema puede ser una situación: Recuperable Se puede manejar y la ejecución puede continuar. Por ejemplo, cuando un bloque de código está esperando un valor en una variable y no está presente. Esto puede ser manejado mediante la ustitución de un valor predeterminado y la ejecución puede continuar. Irrecuperable E una situación grave e irrecuperable , que no se puede manejar. Por ejemplo, un fallo de hardware. Ferreiras JAVA, Exceptions 23 ¿Qué es una excepción1? 1: En el contexto de la ejecución de un programa computacional A bajo nivel, una excepción es un objeto Java con atributos y métodos. El manejo de excepciones debe ser utilizado juiciosamente. Esto es, cuando podemos prever que se puede producir un problema en tiempo de ejecución y conocemos, en tiempo de diseño, de una posible solución, debemos implementar dicha solución. Luego, en tiempo de ejecución, no se deberá alterar el flujo de ejecución del programa, si el problema se presenta. Simplemente registrar el problema y continuar con el flujo no encaja en el manejo de excepciones. Un error, muy común, de los desarrolladores de Java es utilizar el control de excepciones para el control de flujo. Aunque están las instrucciones if...else y otras opciones , tienden a usar como mecanismo de control de flujo el manejo de excepciones, lo cual genera un código malo, mediocre. Ferreiras JAVA, Exceptions 24 1. Se produce el problema. 2. Se crea una excepción. 3. Se tira la excepción. 4. Se maneja o no se maneja la excepción. 1 2 3 4 Ciclo de vida de una excepción Ferreiras JAVA, Exceptions 25 Ciclo de vida de una excepción Después de que un objeto de excepción es creado, éste es traspasado al sistema de tiempo de ejecución ( es tirado, thrown); El sistema de tiempo de ejecución intenta encontrar un manejador para la excepción por el rastreando la lista ordenada de los métodos que habían sido llamados hasta ese momento, llamada como pila de llamadas ( call stack ). Si un manejador de la excepción es encontrado ésta es capturada ( caught ) para ser manejada o, posiblemente, relanzada. Si un manejador de la excepción no es encontrado, no se encuentra el controlador, se imprime por el canal estándar de error ( stderr ) la pila de rastreo de la excepción y el programa aborta su ejecución. Ferreiras JAVA, Exceptions 26 Error, Excepción Un error, Es una situación similar a una excepción, excepto que un error, generalmente, representa un situación irrecuperable y no seria capturado. Los errores no son excepciones en absoluto, sino problemas que surgen fuera del control del usuario o del programador. Típicamente, los errores son ignorados en su código, debido a que casi nunca se puede hacer algo sobre un error. Ferreiras JAVA, Exceptions 27 Error, Excepción Por ejemplo, si se produce un desbordamiento de pila, se producirá un error en tiempo de ejecución, pero es ignorado en tiempo de compilación. Excepciones para tirar Ferreiras JAVA, Exceptions 28 Ejemplos de situaciones que causan excepciones para ser tiradas: De software: llamar un método con un argumento inválido ; De hardware: son iniciadas por el cpu cuando se ejecutan secuencias de códigos inválidas, por ejemplo, división por cero; Excepciones para tirar Ferreiras JAVA, Exceptions 29 Fallo en los recursos de sistema: insuficiencia de memoria, caída de la conexión a la red, ...; Imposibilidad de abrir un archivo; Fallo en los recursos de sistema: insuficiencia de memoria, caída de la conexión a la red, ...; Imposibilidad de abrir un archivo Excepciones para tirar Ferreiras JAVA, Exceptions 30 Petición de una operación de Entrada / Salida que no podría ser completada normalmente; Intento de seguir una referencia nula (null); Intento de ejecutar una operación que viola algún tipo de medida de seguridad. Ferreiras JAVA, Exceptions 31 Tipos de errores de programación De sintaxis: surgen cuando no son respetadas las reglas del lenguaje; son atrapados por el compilador y corregidos por el programador en el código fuente; Ferreiras JAVA, Exceptions 32 En tiempo de ejecución: surgen cuando la aplicación trata de realizar una operación que es imposible de llevar a cabo; deben ser manejados en tiempo de ejecución por el mismo código que esta corriendo; Tipos de errores de programación Ferreiras JAVA, Exceptions 33 Lógicos: surgen cuando los resultados no son los esperados; son detectados en las pruebas de ejecución y deben ser resueltos retrabajando todo el proceso de desarrollo desde el análisis y dominio del problema; Tipos de errores de programación Ferreiras JAVA, Exceptions 34 Manejo de excepciones Es transferir el control de la ejecución del programa a una secuencia de código que se encargará de resolver la situación de error de manera satisfactoria y eficiente. Ferreiras JAVA, Exceptions 35 Notifica al usuario de la ocurrencia del error; Permite continuar la ejecución del programa, si es requerido; Permite terminar la ejecución del programa de manera controlada; El manejo de la excepción: Ferreiras JAVA, Exceptions 36 El manejo de la excepción: Es una forma estructurada de atrapar situaciones completamente inesperadas, como también errores predecibles o resultados inusuales. Facilita la escritura de código más flexible y a prueba de fallas; Ferreiras JAVA, Exceptions 37 Funcionamiento general del manejo de excepciones //... PROBAR{ // HACER TAREA TAREA SI (TAREA_ NO_ SE_ PUEDE_ HACER) TIRAR UNA_ EXCEPCIÓN } CAPATURAR_EXCEPCION( ARGUMENTOS ){ // CODIGO MANEJADOR DE LA EXCEPCIÓN } //... Ferreiras JAVA, Exceptions 38 Después de capturar la excepción Terminar la aplicación: el manejador de la excepción permite indicar al usuario la fuente del error y realizar cualquier tarea de limpieza necesaria antes de la terminación, tal como ejecutar los destructores de los objetos creados en el bloque try-cath, liberando recursos del sistema (memoria). Ferreiras JAVA, Exceptions 39 No terminar la aplicación : quizás el programa puede resolver lo que causo el error y corregirlo, o le requiere al usuario entrar otro tipo de dato. cuando este es el caso, el bloque try-cath son, típicamente, embebidos en un bucle, de manera que el control pueda ser retornado al principio de dicho bloque en el cual fue lanzada la excepción. Ferreiras JAVA, Exceptions 40 Las excepciones NO son para todas la situaciones de error Las excepciones no deben utilizarse para todo tipo de error. estas imponen un cierta sobrecarga en términos de tamaño del programa y tiempo de ejecución. por ejemplo, un error de entrada del usuario (tal como poner letras en campos numéricos) , es más fácil detectarlo en el programa usando estructuras selectivas y repetitivas, en las que se chequea la entrada y se le requiere al usuario probar de nuevo, si es necesario, que usar bloque try-catch. Ferreiras JAVA, Exceptions 41 El mecanismo de excepciones es sorprendentemente sofisticado.cuando una excepción es trhow un destructor es automáticamente llamado para cualquier objeto creado en el código del bloque try-catch. este mecanismo garantiza que el código en dicho bloque ha sido reseteado por lo menos en lo que a la existencia del objeto se refiere. (~\^) Ferreiras JAVA, Exceptions 42 ¿ Qué ocurre si la excepción no es manejada ? La ejecución terminaría abruptamente y, probablemente, no se podrá saber nunca cuál fue la causa; Si es así, las operaciones realizadas en los archivos abiertos se perderán al no guardarse el contenido de los buffer por no ser cerrados Ferreiras JAVA, Exceptions 43 También los objetos creados no serán destruidos y se producirán fugas de memoria; Se podría producir una salida aparatosa llena de mensajes de error que, probablemente, no sean entendidos por el usuario; Ferreiras JAVA, Exceptions 44 Para manejar la excepción, un programa puede ser diseñado para que la procese en una de tres formas. Este puede: No manejar la excepción en absoluto. La JVM se lo informara; Manejar la excepción donde esta ocurre; O Manejar la excepción en otro punto del programa Ferreiras JAVA, Exceptions 45 Manejo de excepciones en JAVA Para manejar las excepciones, donde estas son tiradas, JAVA usa las palabras reservadas try, catch, finally, throws, throw: try{ //... Bloque código que podría disparar la excepción } catch( tipo ){ // ... código que manejaría la excepción } finally { // Código que se ejecutará siempre } Ferreiras JAVA, Exceptions 46 La sentencia try - catch Es obligatoria si se quiere procesar una excepción, esto es, tirarla y capturarla. Se compone de un bloque try y uno o mas bloque catch. Ferreiras JAVA, Exceptions 47 try catch finally El bloque try contiene el conjunto de sentencias que pueden tirar una excepción. Si la excepción es lanzada, un manejador apropiado debe capturarla. Sigue el bloque try y es el bloque para manejar una excepción especifica. Define como manejar un tipo particular de Throwable. Un bloque try puede tener varios bloques catch asociados. Cada bloque catch es llamado un manejador de excepción. Este bloque es opcional. Define una sección de código que es ejecutada siempre. Si es usada, debe ser puesta después del ultimo bloque catch. Puede ser usada para no manejar una excepción tirada en try. No se recomienda usar conjuntamente con catch, crearía confusión. Ferreiras JAVA, Exceptions 48 catch( Exception unaExcepcion ) Captura toda excepción tipo Exception; catch( Error unError ) Captura toda excepción tipo Error catch( Throwable unTiro ) Captura toda excepcion del tipo Exception o Error. Ferreiras JAVA, Exceptions 49 /* Excepcion3b.java jdk1.6.0_25 Ferreiras / JAVA / Exceptions / Excepciones / try-catch-finally Manejando excepciones tipo java.lang.RuntimeException en el lugar donde son tiradas. */ Ferreiras JAVA, Exceptions 50 class ConvertirUnStringAnumeroDouble { ConvertirUnStringAnumeroDouble( ) { try { String cadena = "Ciento Cincuenta pesos con 33/100 "; double numero = Double.parseDouble(cadena); // Esta linea de codigo nunca se ejecutara System.out.println("\n\t=> La cadena " + cadena + " convertida es " + numero + "\n"); } catch ( NumberFormatException unaExcepcion ) { // # 1 System.out.println( "\n\t=> Zoquete(@) : Verifique su codigo !!\n "); } finally { System.out.println("\n\t=> Ejecutando finally...\n"); } } finally Es usado aquí solo con fines didácticos. No es recomendable usar junto con catch porque crearía confusión. Se puede usar sin catch para liberar recursos. Ferreiras JAVA, Exceptions 51 public class Excepcion3b { public static void main(String[] args) { new ConvertirUnStringAnumeroDouble(); } } Ferreiras JAVA, Exceptions 52 /* C:\Archivos de programa\Java\jdk1.6.0_25\bin> java Excepcion3b => Zoquete(@) : Verifique su codigo !! => Ejecutando finally... */ +++++++++++++++++++++++++++++++++++++++++++++++++++++ # 1 Si no es capturada y manejada esta excepcion ( tipo unchecked ): Exception in thread "main" java.lang.NumberFormatException: For input string: "Ciento Cincuenta pesos con 33/100" at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222) at java.lang.Double.parseDouble(Double.java:510) at ConvertirUnStringAnumeroDouble.<init>(Excepcion3b.java:18) at Excepcion3b.main(Excepcion3b.java:41) C:\Archivos de programa\Java\jdk1.6.0_25\bin> */ Es una excepción tipo java.lang.RuntimeException, luego, si es producida será tirada; Si no es capturada y manejada terminará la ejecución del programa. Si es capturada y manejada la ejecución puede seguir. Ferreiras JAVA, Exceptions 53 Hierarchy of the Exception classes Ferreiras JAVA, Exceptions 54 Hierarchy of the Exception classes The Error class describes internal system errors (e.g., VirtualMachineError, LinkageError) that rarely occur. If such an error occurs, there is little that you can do and the program will be terminated by the Java runtime. The Exception class describes the error caused by your program (e.g. FileNotFoundException, IOException). These errors could be caught and handled by your program (e.g., perform an alternate action or do a graceful exit by closing all the files, network and database connections). Exceptions belonging to Error, RuntimeException and their subclasses need not be declared. These exceptions are called unchecked exceptions because they are not checked by the compiler. Ferreiras JAVA, Exceptions 55 Excepciones built-in o predefinidas en JAVA La clase Throwable es la superclase de todas las clases predefinidas de java para indicar todo tipo de situaciones excepcionales: java.lang.Exception java.lang.Error java.lang.Throwable Ver en http://download.oracle.com/javase/6/docs/api/java/lang/Throwable.html Ferreiras JAVA, Exceptions 56 De la clase Exception derivan, entre muchas otras no indicadas aquí: java.lang.Exception java.io.IOException java.lang.RuntimeException Ver todas en http://download.oracle.com/javase/6/docs/api/java/lang/Exception.html Son todas excepciones del tipo “checked” que pueden ocurrir durante las operaciones de Entrada/Salida y procesamiento de archivos ( A ver en otro tema ) Todas las que no son RuntimeException son “checked Exceptions “ ( Ver más adelante ) Ferreiras JAVA, Exceptions 57 Sólo los objetos que son instancias de Throwable (o una de sus subclases) son tirados (throw) por la JVM o, explícitamente, por la sentencia throw de Java. De manera similar, el argumento de catch sólo puede ser del tipo de esta clase o una de sus subclases. Ferreiras JAVA, Exceptions 58 En las excepciones predefinidas ( built-int ) de java hay dos tipos de constructores: Con un parámetro El argumento pasado en este parámetro puede ser mostrado cuando Con un parámetro tipo String El argumento pasado en este parámetro describe el tipo de excepción. En ambos casos el argumento pasado puede ser usado en la sentencia Sistem.out.println() Ver Excepcion14.java Ferreiras JAVA, Exceptions 59 Todas estas clases predefinidas para manejar excepciones en JAVA tienen constructores y métodos ( Ni modo !! ) que usted puede usar para mejor provecho y creatividad en su código de manejo de excepciones. No se preocupe, practique y usted verá que no es difícil. Ferreiras JAVA, Exceptions 60 Dos tipos de excepciones built-in (predefinidas) son de particular interés: Excepciones comprobadas (Checked exceptions) No comprobadas (unchecked) Son todas aquellas que derivan de Exception que no son RuntimeException ni Error; Deben ser declaradas con throws ( a ver mas adelante ) o capturadas en el mismo método. El compilador se mantiene al tanto del trato dado en el programa ( Ver Excepcion14.java ). Son las excepciones RuntimeException y Error . Pueden ser tiradas desde cualquier método. Si no son capturadas pararían la ejecución del programa en el punto donde son producidas, mostrando un mensaje de su ocurrencia. El compilador no se mantiene al tanto de ellas ( Obviamente, pues son de ejecución ). Ferreiras JAVA, Exceptions 61 Exception Reason for Exception ClassNotFoundException This Exception occurs when Java run-time system fail to find the specified class mentioned in the program InstantiationException This Exception occurs when you create an object of an abstract class and interface IllegalAccessException This Exception occurs when you create an object of an abstract class and interface NotSuchMethodException This Exception occurs when the method you call does not exist in class Parte de las excepciones en java.lang.Exception son: Ferreiras JAVA, Exceptions 62 java.lang.Throwable java.lang.Exception java.io.IOException java.io.FileNotFoundException public class FileNotFoundException extends IOException Signals that an attempt to open the file denoted by a specified pathname has failed. This exception will be thrown by the FileInputStream, FileOutputStream, and RandomAccessFile constructors when a file with the specified pathname does not exist. It will also be thrown by these constructors if the file does exist but for some reason is inaccessible, for example when an attempt is made to open a read-only file for writing. FileNotFoundException Es un ejemplo, muy usado, de una excepción checked. http://download.oracle.com/javase/7/docs/api/index.html Ver link indicada mas abajo Ferreiras JAVA, Exceptions 63 try { BufferedReader lector = new BufferedReader(new FileReader(“archivoPlano.txt")); String unaLinea = lector.readLine(); // String readLine() Reads a line of text. } catch( FileNotFoundException fnofObj ) { System.out.println(“\n\t=> Archivo no encontrado\n"); } catch(IOException ioeObj ) { System.out.println(“\n\t=> No puedo leer archivoPlano.txt \n"); } En el tema de Archivos veremos esto con mas detalles. Por ejemplo Este codigo tirará una excepción checked siempre que la operación de E/S sea terminada anormalmente: El constructor FileReather tirará una FileNotFoundException si el archivo indicado no es encontrado. Si el archivo existe, pero por alguna razón el método readLine() no lo puede leer, FileReader lanza una IOException Ferreiras JAVA, Exceptions 64 Para manejar las excepciones checked JAVA utiliza bloques try-catch. Las sentencias del programa que disparan una excepcion son puestas en el bloque try. El bloque catch asociado es el manejador de la excepcion correspondiente. Ferreiras JAVA, Exceptions 65 /* Excepcion14.java jdk1.6.0_25 Ferreiras / JAVA / Excepciones / checked / ParseException */ import java.util.*; import java.text.*; Por ejemplo: Ferreiras JAVA, Exceptions 66 class ComparaFechas { ComparaFechas( ) { try { Date fecha1 = new Date(); // Un objeto fecha con la fecha actual de sistema SimpleDateFormat ff = new SimpleDateFormat (" yyyy-MM-dd"); System.out.println("\n\t=> La fecha actual en formato yyyy-MM-dd es: " + ff.format(fecha1) + "\n"); // mostrar la fecha con el formato ff String cadenaFecha = "07/01/1954"; Date fecha2 = new Date(); fecha2 = ff.parse(cadenaFecha); System.out.println("\n\t=> ++++++++\n" ); System.out.println("\n\t=> La fecha 07/01/1954 en formato yyyy-MM-dd es: " + ff.format(fecha2)+ "\n"); } catch (ParseException e) { System.out.print(e); // Muestra la excepcion generada. Si se quiere, no se muestra } System.out.println("\n\n\t=> Sentencia despues del bloe try/catch\n"); } } Este segmento de código no será ejecutado después de que se genere la excepción Ferreiras JAVA, Exceptions 67 public class Excepcion14 { public static void main(String[ ] args) { new ComparaFechas( ); } } Ferreiras JAVA, Exceptions 68 C:\Program Files\Java\jdk1.6.0_22\bin> java Excepcion14 => La fecha actual en formato yyyy-MM-dd es: 2011-08-12 java.text.ParseException: Unparseable date: "07/01/1954" => Sentencia despues del bloe try/catch C:\Program Files\Java\jdk1.6.0_22\bin> Ferreiras JAVA, Exceptions 69 NOTAS # 1) Si no manejamos con catch la excepcion generada se generara un error de compilacion: C:\Program Files\Java\jdk1.6.0_22\bin> javac Excepcion14.java Excepcion14.java:25: unreported exception java.text.ParseException; must be caught or declared to be thrown ( with throws –ff- ): fecha2 = ff.parse(cadenaFecha); ^ 1 error Para probarlo modifique el codigo escribiendo despues del try // catch (ParseException e) { // System.out.print(e); // Muestra la excepcion generada. // } finally { System.out.println("\n\n\t=> Sentencia despues del bloe try/catch\n"); } # 2) Observes que el codigo a partir de done se genera la excepcion no es ejecutado, dentro del try. # 3 ) Se deja como ejercicio hacer la correccion del ParseException (-_-) Comprueba esto que el compilador se mantiene al tanto de las excepciones checked Ferreiras JAVA, Exceptions 70 Exception Reason for Exception ArithmeticException + These Exception occurs, when you divide a number by zero causes an Arithmetic Exception ClassCastException + These Exception occurs, when you try to assign a reference variable of a class to an incompatible reference variable of another class ArrayStoreException + These Exception occurs, when you assign an array which is not compatible with the data type of that array ArrayIndexOutOfBoundsException These Exception occurs, when you assign an array which is not compatible with the data type of that array Parte de las excepciones en java.lang.RuntimeException son: Ferreiras JAVA, Exceptions 71 NullPointerException + These Exception occurs, when you try to implement an application without referencing the object and allocating to a memory NumberFormatException These Exception occurs, when you try to convert a string variable in an incorrect format to integer (numeric format) that is not compatible with each other NegativeArraySizeException + These are Exception, when you declare an array of negative size. Parte de las excepciones en java.lang.RuntimeException son: Ferreiras JAVA, Exceptions 72 java.lang.RuntimeException – cont- java.lang.RuntimeException AnnotationTypeMismatchException, ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DataBindingException, DOMException,EmptyStackException, EnumConstantNotPresentException, EventException, FileSystemAlreadyExistsException, FileSystemNotFoundException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, IllformedLocaleException, ImagingOpException, IncompleteAnnotationException, IndexOutOfBoundsException, JMRuntimeException, LSException, MalformedParameterizedTypeException, MirroredTypesException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NoSuchMechanismException, NullPointerException, ProfileDataException, ProviderException, ProviderNotFoundException, RasterFormatException, RejectedExecutionException, SecurityException, SystemException, TypeConstraintException, TypeNotPresentException, UndeclaredThrowableException, UnknownEntityException, UnmodifiableSetException, UnsupportedOperationException, WebServiceException, WrongMethodTypeException Ferreiras JAVA, Exceptions 73 java.lang.RuntimeException – cont- ArithmeticException public class ArithmeticException extends RuntimeException Thrown when an exceptional arithmetic condition has occurred. For example, an integer "divide by zero" throws an instance of this class. Ferreiras JAVA, Exceptions 74 java.lang.Error Describe, generalmente, problemas que son sufientemente inusuales y dificiles de recuperarse de ellos. Por ejemplo, Quedarse sin memoria RAM. No es requerido manejar estos errores. Ferreiras JAVA, Exceptions 75 Las excepciones unchecked No es necesario declararlas en la lista de throws ( ver mas adelante ) del método que las tire. Además, el método no tiene que manejarlas, aunque puede, si se quiere. Las escepciones unchecked Por lo general son tiradas (throw) por problemas que surgen en el entorno de la JVM. Por lo tanto, los programadores deben abstenerse de tirar ( throw) estas, es mas conventiente para la JVM que sea ella quien maneje esa parte. Ferreiras JAVA, Exceptions 76 /* Excepcion3a.java jdk1.6.0_22 Ferreiras / JAVA / Exceptions / Excepciones "unchecked" capturadas Las excepciones "unchecked" no tienen que ser tiradas con un throw. Son excepciones built-in dentro de la JVM que las tiras cuando se generan. En este ejemplo son capturadas con catch Por ejemmplo NumberFormatException es una de estas. En este ejemplo se escribe un codigo java incorrecto a proposito para generar la excepcion NumberFormatException y que sea tirada por la JVM, pero es capturada por un catch. */ Ferreiras JAVA, Exceptions 77 class ConvertirUnStringAnumeroDouble { ConvertirUnStringAnumeroDouble( ) { try { String cadena = "Ciento Cincuenta pesos con 33/100 "; double numero = Double.parseDouble(cadena); // Esta linea de codigo nunca se ejecutara System.out.println("\n\t=> La cadena " + cadena + " convertida es " + numero + "\n"); } catch ( NumberFormatException unaExcepcion ) { System.out.println( "\n\t=> Zoquete(@) : Verifique su codigo !!\n "); } } } Ferreiras JAVA, Exceptions 78 public class Excepcion3a { public static void main(String[] args) { new ConvertirUnStringAnumeroDouble(); } } C:\Archivos de programa\Java\jdk1.6.0_25\bin> java Excepcion3a => Zoquete(@) : Verifique su codigo !! C:\Archivos de programa\Java\jdk1.6.0_25\bin> Ferreiras JAVA, Exceptions 79 /* C:\Archivos de programa\Java\jdk1.6.0_25\bin> java Excepcion3 Exception in thread "main" java.lang.NumberFormatException: For input string: "Ciento Cincuenta pesos con 33/100" at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222) at java.lang.Double.parseDouble(Double.java:510) at ConvertirUnStringAnumeroDouble.<init>(Excepcion3.java:60) at Excepcion3.main(Excepcion3.java:72) */ Ahora ya lo entiende. Vimos, en Excepcion3.java, que la excepción no fue capturada ni manejada Ferreiras JAVA, Exceptions 80 Propagación de excepciones Es la captura y manejo de una excepción en un lugar (nivel) diferente a donde ésta fue tirada. Dicha captura y manejo es hecha en un método específico diferente al que la originó. Ferreiras JAVA, Exceptions 81 La propagación de excepciones Es posible porque, si una excepción no es capturada en el lugar donde esta ocurre, el control de la ejecución es inmediatamente retornado al método que invocó el método que produjo la excepción. Ferreiras JAVA, Exceptions 82 La propagación de excepciones: Evita la dispersion del manejo de las excepciones; Si no hay un bloque catch para capturar y manejar una excepción esta es enviada el método invocado; Todas las ejecuciones son ignoradas hasta encontrar el manejador de excepciones. Ferreiras JAVA, Exceptions 83 /* Excepcion4.java jdk1.6.0_22 Ferreiras / JAVA / Exceptions / Propagacion de excepciones */ class ConvertirUnStringAnumeroDouble { ConvertirUnStringAnumeroDouble( ) { nivelUno(); } Por ejemplo: Ferreiras JAVA, Exceptions 84 public void nivelUno( ) { System.out.println("\n\t=> Nivel uno iniciando...\n"); try { nivelDos(); } catch ( NumberFormatException exception ) { System.out.println( "\n\t=> Zoquete(@) : Verifique su codigo !!\n "); } System.out.println("\n\t=> Nivel uno terminando...\n"); } public void nivelDos( ) { System.out.println("\n\t=> Nivel dos iniciando...\n"); nivelTres( ); System.out.println("\n\t=> Nivel dos terminando...\n"); } Ferreiras JAVA, Exceptions 85 public void nivelTres( ) { System.out.println("\n\t=> Nivel tres iniciando...\n"); String cadena = "Ciento Cincuenta pesos con 33/100 "; double numero = Double.parseDouble(cadena); // Esta linea de codigo nunca se ejecutara System.out.println("\n\t=> La cadena " + cadena + " convertida es " + numero + "\n"); System.out.println("\n\t=> Nivel tres terminando...\n"); } } // Fin clase ConvertirUnStringAnumeroDouble public class Excepcion4 { public static void main(String[] args) { new ConvertirUnStringAnumeroDouble(); } } Ferreiras JAVA, Exceptions 86 /* C:\Archivos de programa\Java\jdk1.6.0_25\bin> java Excepcion4 => Nivel uno iniciando... => Nivel dos iniciando... => Nivel tres iniciando... => Zoquete(@) : Verifique su codigo !! => Nivel uno terminando... C:\Archivos de programa\Java\jdk1.6.0_25\bin> */ Ferreiras JAVA, Exceptions 87 Tirar excepciones: throw, throws Es la creación manual de un objeto Exception y el manejo de éste en el sistema de ejecución . Para tirar manualmente una excepción se utiliza la palabra clave ”throw” en una sentencia if dentro de un bloque try. La palabra reservada “throws” se utiliza en la firma del método para indicar, a sus usuarios, que éste tiene “inteligencia” para tirar una o mas excepciones. Ferreiras JAVA, Exceptions 88 //... try { // código if (condición) { throw new Exception("Error"); } // código } catch (Exception e) { // informar de la excepción al usuario } //... Por ejemplo ( try-throw-catch ): Mecanismo try-throw-catch Ferreiras JAVA, Exceptions 89 especificadorAcceso tipoRetorno nombreMetodo ( T1 par1, T2, par2, ...) throws excepcionTipo1, excepcionTipo2, ... { //...código if (condición) { throw new Exception("Error");} // código } Por ejemplo ( throws ) No captura la excepción, simplemente la tiraría. Ferreiras JAVA, Exceptions 90 especificadorAcceso tipoRetorno nombreMetodo ( T1 par1, T2, par2, ...) throws excepcionTipo1, excepcionTipo2, ... { //...código try { metodoTiraExcepcion(); } // código finally { // código } } Por ejemplo ( throws ) No captura la excepción, simplemente la tiraría por medio de llamar metodoTiraExcepcion(), EL CUAL debe indicar con un throws que puede tirar excepciones. Ferreiras JAVA, Exceptions 91 ... Finalmente, en el código del programador habrá un método que no tiene throws, que deberá capturar y manejar las excepciones. Ferreiras JAVA, Exceptions 92 ¿ Manejar o No manejar la excepción tirada ? La excepción tirada manualmente dentro de un método podrá ser o no manejada. Eso esta a opción de la filosofía del desarrollador. Se ha escrito y se sigue escribiendo mucho acerca de esto. Ver en el grupo el archivo “Throwing exceptions.doc” y hacer un resumen ejecutivo de su opinión. Ferreiras JAVA, Exceptions 93 /* Excepcion5.java jdk1.6.0_25 Ferreiras / JAVA / exceptions / throw, throws */ class TirandoExcepciones { int num; int div; public int divideEnteros( ) throws RuntimeException { if( div == 0) throw new RuntimeException("\n\t=> Zoquete(@), no se puede dividir por cero !!\n "); return num / div; } El objeto RuntimeException se construirá con esta cadena que mas adelante podremos mostrar en catch Este código tira una RuntimeException, lo cual no es correcto, aunque usted vea que fundione. Reescríbalo de nuevo haciendo la corrección. Ferreiras JAVA, Exceptions 94 // - continuacion de la clase TirandoExcepciones - TirandoExcepciones( int numerador, int divisor ) { num = numerador; div = divisor; } public void llamaDivideEnteros( ) { try { System.out.println( "\n\t=> Cociente = " + divideEnteros() + "\n\t=> " ); } catch (RuntimeException unaExcepcion) { unaExcepcion.printStackTrace(); // Muestra la excepcion en la pila System.out.println("\n\t=> Se manejo la excepcion !!\n"); } } } // Fin de la clase TirandoExcepciones printStackTrace() es un metodo Throwable que contiene informacion acerca de la causa del fallo, ademas de mostrar la cadena usada al construir el objeto con throw. Ferreiras JAVA, Exceptions 95 class usoClases { usoClases( ) { TirandoExcepciones te1 = new TirandoExcepciones( 23, 4 ); te1.llamaDivideEnteros(); TirandoExcepciones te2 = new TirandoExcepciones( 23, 0 ); te2.llamaDivideEnteros(); } } public class Excepcion5 { public static void main(String[] args) { new usoClases(); } } Ferreiras JAVA, Exceptions 96 C:\Program Files\Java\jdk1.6.0_22\bin> java Excepcion5 => Cociente = 5 => java.lang.RuntimeException: => Zoquete(@), no se puede dividir por cero !! at TirandoExcepciones.divideEnteros(Excepcion5.java:16) at TirandoExcepciones.llamaDivideEnteros(Excepcion5.java:27) at usoClases.<init>(Excepcion5.java:43) at Excepcion5.main(Excepcion5.java:52) => Se manejo la excepcion !! C:\Program Files\Java\jdk1.6.0_22\bin> Toda esta informacion se obtiene con el metodo Throwable printStackTrace() Ferreiras JAVA, Exceptions 97 Tirando excepciones throw, throws En situaciones en las que el desarrollador puede predecir una excepción, entonces esta puede ser explícitamente tirada cuando se cumplan las condiciones para ello; Hasta ahora hemos estado manejando excepciones tiradas por la JVM. No obstante es posible tirarlas explícitamente usando throw. La palabra reservada throw indica una sentencia que causa que una excepción sea iniciada. Toma como argumento un objeto del tipo de la excepción a ser tirada: throw new tipoExcepcion( ); new tipoExcepcion( ) Es el objeto. Ferreiras JAVA, Exceptions 98 Tirando excepciones throw, throws El flujo de ejecución se detiene inmediatamente después de que la sentencia throw es tirada. El bloque try más cercano es inspeccionado para ver si tiene una sentencia catch que coincida con el tipo de la excepción. Si no encuentra una que coincida el control se transfiere al próximo catch. Si se encuentra coincidencia, entonces el valor por defecto del controlador de excepciones detiene el programa e imprime el seguimiento de la pila ( printStackTrace() ). Ferreiras JAVA, Exceptions 99 Las excepciones de tipo RuntimeException ( que son muy comunes ) no es necesario declararlas en la clausula throws ( Y entonces, en el ejemplo Excepcion5.java ) ?? Tirando excepciones throw, throws Si un método invoca otro método que tira una excepción checked, esta forzado a pasar la excepción o a capturarla; Ferreiras JAVA, Exceptions 100 Declaring Exceptions A Java method must declare in its signature the types of checked exception it may "throw" from its body, via the keyword "throws". For example, suppose that methodD() is defined as follows: public void methodD() throws XxxException, YyyException { // method body throw XxxException and YyyException }The method's signature indicates that running methodD() may encounter two checked exceptions: XxxException andYyyException. In other words, some of the abnormal conditions inside methodD() may trigger XxxException orYyyException. Exceptions belonging to Error, RuntimeException and their subclasses need not be declared. These exceptions are calledunchecked exceptions because they are not checked by the compiler. Tirando excepciones throw, throws Ferreiras JAVA, Exceptions 101 Throwing an Exception When a Java operation encounters an abnormal situation, the method containing the erroneous statement shall create an appropriate Exception object and throw it to the Java runtime via the statement "throw XxxException". For example, Tirando excepciones throw, throws Ferreiras JAVA, Exceptions 102 Throwing an Exception public void methodD() throws XxxException, YyyException { // method's signature // method's body ... ... // XxxException occurs if ( ... ) throw new XxxException(...); // construct an XxxException object and throw to JVM ... // YyyException occurs if ( ... ) throw new YyyException(...); // construct an YyyException object and throw to JVM ... } Note that the keyword to declare exception in the method's signature is "throws" and the keyword to throw an exception object within the method's body is "throw". . Tirando excepciones throw, throws Ferreiras JAVA, Exceptions 103 Excepciones definidas por el programador. Son diseñadas por el desarrollador cuando este no encuentra una en la jerarquía de clase Throwable que le permita manejar una condición excepcional en particular, en la cual una excepción prevista debe ser explícitamente tirada cuando se cumpla una condición. Para ello se extends una clase en la jerarquía de Throwable. Ferreiras JAVA, Exceptions 104 Dos constructores deben ser proporcionado por nuestra propia clase manejadores de excepciones: a) Un con constructor sin parámetros; Y, b) Un constructor con un parámetro tipo String para recibir como argumento una cadena de mensaje que describe la razón de la excepción. Ferreiras JAVA, Exceptions 105 Se debe extender la clase apropiada en la jerarquía Throwable, Seleccionando una clase que describa la situación lo mas cerca posible. Ferreiras JAVA, Exceptions 106 /* Excepcion11.java jdk1.6.0_22 Ferreiras / JAVA / Exceptions/ Excepciones definidas por el Programador En este código manejamos diferentes excepciones conocidas por el desarrollador. No podemos usar diferentes bloques catch para capturar un tipo RuntimeException por todos tirarían el mismo tipo. Lo que necesitamos es una excepción única para cada tipo de error. */ Ferreiras JAVA, Exceptions 107 import java.util.Scanner; class ExcepcionMuyPequeno extends Exception { public ExcepcionMuyPequeno( ) { super( "\n\t=> Numero muy pequeno\n"); } // +++++++++++++++++++++++++++++++++++ public ExcepcionMuyPequeno( String mensaje ) { super(mensaje); } } Observece que se proporcionan los dos tipos de constructoires antes indicados. Ferreiras JAVA, Exceptions 108 // +++++++++++++++++++++++++++++++++++++++ class ExcepcionMuyGrande extends Exception { public ExcepcionMuyGrande( ) { super( "\n\t=> Numero muy grande\n"); } // ++++++++++++++++++++++++++++++++++++ public ExcepcionMuyGrande( String mensaje ) { super (mensaje ); } } Ferreiras JAVA, Exceptions 109 class usoClases { usoClases( ) { Scanner lector = new Scanner( System.in ); System.out.print( " \n\t => Entre un numero: " ); int x = lector.nextInt() ; try { if ( x < 100 ) throw new ExcepcionMuyPequeno(); if( x > 200 ) throw new ExcepcionMuyGrande("\n\t=> El numero " + x + " es muy grande" ); } catch( ExcepcionMuyPequeno unaExcepcion ) { System.out.println( unaExcepcion.getMessage() ); System.out.println( "\n\t=> La proxima vez entre un numero mas grade\n" ); } catch( ExcepcionMuyGrande unaExcepcion ) { System.out.println( unaExcepcion.getMessage() ); System.out.println( "\n\t=> La proxima vez entre un numero mas pequeno\n" ); } } } Ferreiras JAVA, Exceptions 110 public class Excepcion11 { public static void main( String [ ] args ) { new usoClases( ); } } Ferreiras JAVA, Exceptions 111 C:\Program Files\Java\jdk1.6.0_22\bin> java Excepcion11 => Entre un numero: 23 => Numero muy pequeno => La proxima vez entre un numero mas grade C:\Program Files\Java\jdk1.6.0_22\bin>java Excepcion11 => Entre un numero: 234 => El numero 234 es muy grande => La proxima vez entre un numero mas pequeno C:\Program Files\Java\jdk1.6.0_22\bin>java Excepcion11 => Entre un numero: 155 C:\Program Files\Java\jdk1.6.0_22\bin> Ferreiras JAVA, Exceptions 112 Finally, Usar o no Usar las excepciones en nuestro código? Ver en el grupo “When to throw an exception.doc” y “The Ariane Rocket Incidenty.doc”;Luego, hacer un resumen ejecutivo al profesor de su opinión about it. Ferreiras JAVA, Exceptions 113 Finally, Usar o no Usarlas excepciones en nuestro código? Exception Handling By S Leistikow, 7 May 2013 http://www.codeproject.com/Articles/589514/ExceptionplusHandling A popular phrase among developers is to "Fail fast and fail often." I'm not saying this is wrong, but I'm not saying this is right either. The idea to fail fast is to get immediate feedback that something bad happened. Letting an unhandled exception close the application isn't always acceptable, either. I don't think it's acceptable at all, even for work tools to have an unhandled exception, but that means you've came up with a way to handle every single exception possible. That is very unlikely. Software development is a craft in this regard because you have to find a balance. My rule of thumb is if I can recover from an exception, then I need to ensure that my application can recover. It's not exactly rocket science. I believe the key is to ensure that you never throw a generic exception. Each exception that you throw needs to be specific to the issue or problem at hand. That way you catch that specific exception and not a similar exception from lower level classes. You also never want to handle a generic exception, either. Sometimes you won't be able to recover from a specific exception and so it's perfectly fine to let it get deferred to a higher level class to handle it correctly. Ferreiras JAVA, Exceptions 114 Finally, Usar o no Usarlas excepciones en nuestro código? ... The balance comes when you're at the highest level and you're getting exceptions that were thrown levels down. You may not be able to catch all of them, because you may not know what exceptions were not handled in the levels below. In .NET it's really easy to send your department information when an unhandled exception occurs. It's not the best way and it may not always be the right way, but sometimes it's the only way to properly find out what type of exceptions are being thrown. I'd rather have the application crash then to have my end user using an application where the state is unknown. This can lead to more problems and issues. Software development is something you craft and with time you'll be able to learn and generate better exception handlers. Don't throw generic exceptions and don't handle generic exceptions, because if it's generic then you have no idea what really happened. Leaving an end user with the ability to do more damage is never the way to go. Ferreiras JAVA, Exceptions 115 Referencias Big Java: Compatible with Java 5, 6 and 7; Cay S. Horstmann; Wiley, 4th. edition; 2009 Java Software Solutions: Foundations of Program Design; John Lewis and William Loftus; 7th Edition; 2011 Documentación API Java Java™ Platform, Standard Edition 7 API Specification http://download.oracle.com/javase/7/docs/api/ javapapers.com/core-java/exception-handling http://docs.oracle.com/javase/tutorial/essential/exceptions/ https://thenewcircle.com/bookshelf/java_fundamentals_tutorial/exceptions.html Ferreiras JAVA, Exceptions 116 GRACIAS
Compartir