Programación interactiva Oscar Bedoya oscarbed@eisc.univalle.edu.co Excepciones • Una excepción es la indicación de un problema que ocurre durante la ejecución de un programa • El manejo de excepciones permite a los programadores crear aplicaciones que pueden resolver las excepciones •Cuando se genera una excepción en un programa éste aborta su ejecución. El manejo de una excepción permite que el programa continúe su ejecución Excepciones ver PruebaDivisionEntreCero Excepciones java.lang.ArithmeticException: / by zero Excepciones ¿Qué ocurre cuando se ejecutan las siguientes instrucciones? int valores[]=new int[10]; valores[12]=2007; Excepciones int valores[]=new int[10]; valores[12]=2007; java.lang.ArrayIndexOutOfBoundsException: 12 Excepciones Throwable Exception RuntimeException Error IOException Throwable: superclase que almacena un mensaje con el tipo de anormalidad que se produjo Excepciones Throwable Exception Error Error: subclase de Throwable que indica problemas graves que una aplicación no debería intentar solucionar Ejemplo: memoria RuntimeException IOException agotada, error interno de la JVM Excepciones Exception: relacionado con subclases para situaciones que una aplicación debería tratar de forma razonable Throwable Exception RuntimeException Error IOException •RunTimeException: errores que puede tratar el programador como una división por cero o el acceso fuero de los limites de un arreglo •IOException: errores que no puede evitar el programador, generalmente relacionados con operaciones de entrada/salida Excepciones • Considere el problema de la división entre cero numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; El programador conoce los puntos en el código donde puede ocurrir una excepción y además, debe saber qué tipo de excepción se genera y cómo solucionarlo Excepciones • Qué problemas pueden ocurrir en este código? numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; Excepciones • Qué problemas pueden ocurrir en este código? numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; -Se espera que el usuario ingrese dos números enteros, si el usuario ingresa cualquier otro tipo de dato se producirá una excepción -Se espera que numero2 sea diferente de 0, si es 0, se producirá una excepción -El usuario no ingresa ningún valor y oprime enter Excepciones • Java proporciona una instrucción para el manejo de eventuales excepciones try{ código java donde podría ocurrir una excepción } catch (TipoExcepcion objeto){ instrucciones a ejecutar si se produce una excepción de TipoExcepcion } Excepciones Tipo Excepción Descripción ArithmeticException Errores Matemáticos, como división por cero ArrayIndexOutOfBoundsException Un programa tratando de almacenar un dato en una posición no válids de un arreglo FileNotFoundException IOException NullPointerException NumberFormatException SecurityException Un intento de acceder a un archivo que no existe Fallas de entrada/salida, tal como la inhabilidad de leer desde un archivo Referencia a un objeto NULL Una conversión fallida entre Strings y números Un applet tratando de realizar una acción no permitida por la configuración de seguridad del browser Excepciones numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; Excepciones numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (ArithmeticException excepcionArimetica){ JOptionPane.showMessageDialog(null, “El denominador debe ser distinto de 0”); campoEntrada2.setText(“”); } PruebaDivisonEntreCero Excepciones numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; Se está manejando solo uno de los casos de error try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (ArithmeticException excepcionArimetica){ JOptionPane.showMessageDialog(null, “El denominador debe ser distinto de 0”); campoEntrada2.setText(“”); } Excepciones try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (ArithmeticException excepcionArimetica){ JOptionPane.showMessageDialog(null, “El denominador debe ser distinto de 0”); campoEntrada2.setText(“”); } catch (NumberFormatException excepcionFormato) { JOptionPane.showMessageDialog(null, "Deben ser números enteros"); campoEntrada1.setText(""); campoEntrada2.setText(""); } Excepciones try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (ArithmeticException excepcionArimetica){ JOptionPane.showMessageDialog(null, “El denominador debe ser distinto de 0”); campoEntrada2.setText(“”); } catch (NumberFormatException excepcionFormato) { JOptionPane.showMessageDialog(null, "Deben ser números enteros"); campoEntrada1.setText(""); campoEntrada2.setText(""); } Se pueden colocar varias instrucciones catch, cada una captura un tipo de excepción diferente Excepciones try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (ArithmeticException excepcionArimetica){ JOptionPane.showMessageDialog(null, “El denominador debe ser distinto de 0”); campoEntrada2.setText(“”); } catch (NumberFormatException excepcionFormato) { JOptionPane.showMessageDialog(null, "Deben ser números enteros"); campoEntrada1.setText(""); campoEntrada2.setText(""); } PruebaDivisonEntreCero1 Excepciones • Manejo de excepciones con la clase Exception try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (Exception excepcion){ JOptionPane.showMessageDialog(null, “Se produjo una excepción”); System.out.println(excepcion.toString()); } Excepciones • Manejo de excepciones con la clase Exception try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (Exception excepcion){ JOptionPane.showMessageDialog(null, “Se produjo una excepción”); System.out.println(excepcion.toString()); } Se utiliza de manera general la clase Exception. No se puede especificar el tipo de excepción que ocurre Excepciones • Manejo de excepciones con la clase Exception try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (Exception excepcion){ JOptionPane.showMessageDialog(null, “Se produjo una excepción”); System.out.println(excepcion.toString()); } Cada excepción tiene asociado un texto que indica lo que ha ocurrido Excepciones • Manejo de excepciones con la clase Exception try{ numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = numero1/numero2; } catch (Exception excepcion){ JOptionPane.showMessageDialog(null, “Se produjo una excepción”); System.out.println(excepcion.toString()); } PruebaDivisonEntreCero2 Excepciones Cláusula finally • El manejo de excepciones se completa con la cláusula finally • Esta cláusula contiene código que se ejecuta en cualquier caso, es decir, así haya o no ocurrido una excepción • Su utilidad está relacionada con aplicaciones que requieren guardar un archivo log de las “actividades” realizadas en el programa. También es útil para colocar código que libere recursos, por ejemplo, cerrar un archivo sabiendo que ya se ejecutaron las operaciones sobre el mismo Excepciones try{ código java donde podría ocurrir una excepción instrucciones para adquirir recursos } catch (TipoExcepcion objeto){ instrucciones a ejecutar si se produce una excepción de TipoExcepcion } finally{ instrucciones instrucciones para liberar recursos } Excepciones Cláusula throws • En la declaración de un método, la cláusula throws especifica las excepciones que se pueden lanzar en ese método • La cláusula contiene una lista separada por comas de las excepciones que lanzará el método •Las excepciones lanzadas deben ser capturadas con un try-catch en cuyo cuerpo se hace el llamado al método Excepciones public int cociente( int numerador, int denominador ) throws ArithmeticException, NumberFormatException { return numerador / denominador; } Excepciones public int cociente( int numerador, int denominador ) throws ArithmeticException, NumberFormatException { return numerador / denominador; } Se establece que el método puede generar excepciones de tipo ArithmeticException y NumberFormatException Las excepciones lanzadas deben ser capturadas con un try-catch en cuyo cuerpo se hace el llamado al método try { numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = cociente(numero1,numero2); campoSalida.setText( String.valueOf( resultado ) ); } catch (ArithmeticException excepcionAritmetica ) { JOptionPane.showMessageDialog(null, "El denominador debe ser diferente de 0", "Excepción aritmética", JOptionPane.ERROR_MESSAGE campoEntrada2.setText(""); } ); Las excepciones lanzadas deben ser capturadas con un try-catch en cuyo cuerpo se hace el llamado al método try { numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = cociente(numero1,numero2); campoSalida.setText( String.valueOf( resultado ) ); } catch (ArithmeticException excepcionAritmetica ) { JOptionPane.showMessageDialog(null, "El denominador debe ser diferente de 0", "Excepción aritmética", JOptionPane.ERROR_MESSAGE campoEntrada2.setText(""); } Método en el que se pueden generar las excepciones ); Las excepciones lanzadas deben ser capturadas con un try-catch en cuyo cuerpo se hace el llamado al método try { numero1 = Integer.parseInt( campoEntrada1.getText() ); numero2 = Integer.parseInt( campoEntrada2.getText() ); resultado = cociente(numero1,numero2); campoSalida.setText( String.valueOf( resultado ) ); } catch (ArithmeticException excepcionAritmetica ) { JOptionPane.showMessageDialog(null, "El denominador debe ser diferente de 0", "Excepción aritmética", JOptionPane.ERROR_MESSAGE campoEntrada2.setText(""); } Método en el que se pueden generar las excepciones PruebaDivisonEntreCero3 ); Excepciones Creando excepciones propias • Para crear un excepción propia se debe crear una clase que herede de la clase Exception • Para lanzar la excepción, se utiliza la instrucción throw new NombreExcepcion(); Excepciones Creando excepciones propias • Para crear un excepción propia se debe crear una clase que herede de la clase Exception • Para lanzar la excepción, se utiliza la instrucción throw new NombreExcepcion(); Empleado ExceptionCapacidadEmpresa Empresa public class ExceptionCapacidadEmpresa extends Exception { ExceptionCapacidadEmpresa(String nombre) { super("No es posible añadir el empleado " + nombre); } } public class ExceptionCapacidadEmpresa extends Exception { ExceptionCapacidadEmpresa(String nombre) { super("No es posible añadir el empleado " + nombre); } } Toda excepción tiene un mensaje que se muestra cuando ocurra. Con super se pasa a Exception cuál es el mensaje a mostrar Capturando una excepción lanzada con throw try{ ingresarEmpleado(); }catch(ExceptionCapacidadEmpresa e ){ System.out.println(e.toString()); JOptionPane.showMessageDialog(null, "Error”); } Capturando una excepción lanzada con throw try{ ingresarEmpleado(); }catch(ExceptionCapacidadEmpresa e ){ System.out.println(e.toString()); JOptionPane.showMessageDialog(null, "Error en la capacidad de empleados”); } El método toString muestra el mensaje de error que tiene la excepción