8 - CAPTURAR EXCEPCIONES Programación Orientada a Objetos Proyecto Curricular de Ingeniería de Sistemas CAPTURAR EXCEPCIONES Las excepciones lanzadas por un método que pueda hacerlo deben recoger en bloque try/catch o try/finally. package exeptions; public class Melon{ public static void main (String args[]){ int valor; try { int x; for( x=0,valor = 100; x < 100; x ++ ) valor /= x; } catch( ArithmeticException e ) { System.out.println( "Matemáticas locas!" ); } catch( Exception e ) { System.out.println( "Se ha producido un error" ); } } } try Es el bloque de código donde se prevé que se genere una excepción. Es como si dijésemos "intenta estas sentencias y mira a ver si se produce una excepción". El bloque try tiene que ir seguido, al menos, por una cláusula catch o una cláusula finally catch Es el código que se ejecuta cuando se produce la excepción. Es como si dijésemos "controlo cualquier excepción que coincida con mi argumento". En este bloque tendremos que asegurarnos de colocar código que no genere excepciones. 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, como esta: catch( Excepcion e ) { ... 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. 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. 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. Veamos un ejemplo completo que realice manejo de excepciones, este programa presenta un applet simple para duplicar números (multiplicarlo por 2), que le solicita al usuario un entero en un campo de tipo textField y luego muestra el resultado: Los resultados que el programa generaría al final serian: Si el usuario ingresa el numero 2546, el resultado seria: El valor duplicado es 5092 ó si ingresa el String Hola Mundo, el resultado seria: Error en el número: vuelva a escribir. Se aclara que la aplicación funciona una vez ingresados los datos y presionado la techa Intro (Enter). package exeptions; import java.awt.*; import java.applet.Applet; import java.util.*; import java.awt.event.*; public class ExcepcionDemo1 extends Applet implements ActionListener { private TextField cadenaCampo; private TextField resultadoCampo; private Label resultadoEtiqueta, cadenaEtiqueta; public void init() { cadenaEtiqueta = new Label("Introduzca un entero: "); resultadoEtiqueta = new Label("Respuesta: "); cadenaCampo = new TextField(30); resultadoCampo = new TextField(30); resultadoCampo.setEditable(false); add(cadenaEtiqueta); add(cadenaCampo); cadenaCampo.addActionListener(this); add(resultadoEtiqueta); add(resultadoCampo); } public void actionPerformed(ActionEvent event) { if (event.getSource() == cadenaCampo) { try { int numero = Integer.parseInt(cadenaCampo.getText()); resultadoCampo.setText("El valor duplicado es "+(2*numero)); } catch (NumberFormatException e) { resultadoCampo.setText("Error en el número: vuelva a escribir "); } } } } Las siguientes figuras muestran la forma en que se comporta la aplicación al ingresar un número y un String: La parte clase de este programa es: try { int numero = Integer.parseInt(cadenaCampo.getText()); resultadoCampo.setText("El valor duplicado es "+(2*numero)); } catch (NumberFormatException e) { resultadoCampo.setText("Error en el número: vuelva a escribir "); } Aquí es donde se dice “Si algo sale mal dentro del parseInt, encárgate de ello catch”. La excepción de la clase NumberFormatException es lanzada cuando el método parseInt en su parámetro de entrada no tiene un valor entero valido para convertir de String a Entero, por ejemplo una oración “Hola”. Si ocurre otro tipo de excepción el bloque cath no se ejecutara y JAVA intentara encontrar un catch que especifique este tipo de excepción. Ahora se describirá el error que ocurre en la aplicaron anterior: En el ejemplo se tiene catch (NumberFormatException e) { Que es la declaración de un método, este recibe como parámetros de entrada un objeto de tipo NumberFormatException llamado e, este objeto contiene la información de la excepción, si se desea imprimir mas información acerca de la excepción se puede realizar a través del método toString(), este método devuelve el nombre de la excepción junto con un posible mensaje adicional que lo clarifica, por ejemplo se podría reescribir el fragmento de código por: catch (NumberFormatException e) { resultadoCampo.setText("Error: " + e.toString()); } El método toString retorna el nombre de la excepción junto con un posible mensaje adicional que lo clarifica, la instrucción anterior produce el mensaje: Error: java.lang.NumberFormatException: For input string: "Hola" Ejercicio para el lector: Modifique el programa anterior para realizar una división y controle la excepción de la división por 0, adicional a la del Formato del numero (NumberFormatException).