Download catch - DBA.MX
Document related concepts
no text concepts found
Transcript
Java: Excepciones Introducción • Una excepción es una situación anómala que surge en un bloque de código, es decir, es un error que normalmente aparece en tiempo de ejecución • ¿Qué ocurre con una excepción? – Cuando se genera una excepción el interprete crea un objeto para representar la excepción – Envía el objeto (la excepción) al método que ha provocado la excepción – Si el método no captura la excepción, entonces el interprete la captura y realiza las acciones pertinentes (detención del programa y avisos o mensajes por pantalla) • Java tiene un sistema para que el programador defina la captura y gestión de las excepciones 2 ¿No quiere gestionar excepciones? En el siguiente ejemplo el programador no gestiona excepciones: java.lang.ArrayIndexOutOfBoundsException: 3 at j11_excepciones.j11_excepciones.main(j11_excepciones.java:7) Exception in thread "main" public class j11_excepciones { public static void main(String[] args) { int a[] = new int[3]; for ( int i = 0; i <= 3; i++) a[i] = i; fun( a ); } static void fun(int b[]) { b[2] = 1 / b[0]; } } El interprete lanza una excepción del tipo (clase) ArrayIndexOutOfBoundsException, es decir, el error se ha producido por intentar acceder a una posición externa a la matriz. Además el interprete nos informa de la posición o índice incorrecto dentro de la matriz (3), así como del método que ha provocado la excepción java.lang.ArithmeticException: / by zero at j11_excepciones.j11_excepciones.fun(j11_excepciones.java:11) at j11_excepciones.j11_excepciones.main(j11_excepciones.java:8) Exception in thread "main" El interprete lanza una excepción del tipo (clase) ArithmeticException, es decir, el error se produce al dividir uno por cero. El interprete nos informa además del método que produjo la excepción 3 try/catch/finally • Capturamos y gestionamos excepciones por medio de: – try: ejecuta un bloque de código y lanza la excepción a la primera sentencia catch que gestione ese tipo de excepción – catch: captura la excepción y realiza las acciones correspondientes – finally: se ejecuta al final de try y después de catch, además captura las excepciones no capturadas por una sentencia catch • Formato: try { // bloque de código en el que gestionamos la excepción } catch ( tipo_excepción1 objeto ) { // Gestión de tipo_excepción1 } catch ( tipo_excepción2 objeto ) { // Gestión de tipo_excepción2 } finally { // Gestión de otras excepciones } 4 Ejemplo • En el siguiente ejemplo se gestiona la excepción: public static void main(String[] args) { try { int a[] = new int[3]; for (int i = 0; i <= 3; i++) a[i] = i; System.out.println( "Esto no se imprime, ¿por qué?" ); } catch (ArrayIndexOutOfBoundsException e) { System.out.println( "Error de acceso fuera de limite de matriz" ); System.out.println( "Índice erroneo:" + e.getMessage() ); } finally { System.out.println( "finally" ); } } • El objeto tiene un método printStackTrace(), no utilizado en el ejemplo, para mostrar el mensaje de error. La salida por pantalla del ejemplo es: Error de acceso fuera de limite de matriz Índice erroneo:3 Finally • Pruebe a gestionar las excepciones del ejemplo anterior, fun() 5 Jerarquia de excepciones • Las excepciones están representadas en una jerarquía de herencia, por ejemplo para nuestro anterior ejemplo: java.lang.Object | +--java.lang.Throwable | +--java.lang.Exception | +--java.lang.RuntimeException | +--java.lang.IndexOutOfBoundsException | +--java.lang.ArrayIndexOutOfBoundsException • Para más información consulte la ayuda del JDK o los numerosos libros que tratan el tema, por ejemplo: Niemeyer y Knudsen (2000, p. 142-3) 6 • catch múltiples Puede poner múltiples catch, ya que un mismo bloque de código puede producir diversas excepciones. Pero tenga en cuenta la jerarquía de clases de excepciones y ponga las subclases antes de la clases. En el siguiente ejemplo, el primer catch atrapa la excepción ArrayIndexOutOfBoundsException y el segundo el resto de excepciones de RuntimeException (su clase “abuela”): try { int a[] = new int[3]; for (int i = 0; i <= 3; i++) a[i] = i; } catch (ArrayIndexOutOfBoundsException e) { System.out.println( "Error de acceso fuera de limite de matriz" ); } catch (RuntimeException e ) { System.out.println( "Error en tiempo de ejecución" ); } • Si lo hacemos al revés (ponemos primero la clase “abuela”), el código del segundo catch nunca se ejecutaría (sólo se ejecuta un catch). El compilador nos informa del error: “catch fuera de ámbito”: catch (RuntimeException e ) { System.out.println( "Error en tiempo de ejecución" ); } catch (ArrayIndexOutOfBoundsException e) { // ERROR: Nunca se ejecuta System.out.println( "Error de acceso fuera de limite de matriz" ); } 7 • throws La cláusula throws indica al compilador las excepciones que un método puede lanzar. Es necesario para todas las excepciones, salvo para las del tipo Error o RuntimeException (y sus subclases). En el siguiente ejemplo usamos una entrada por teclado, lo cual nos obliga a declarar (throws) las excepciones IOException que pueden ser lanzadas (si no lo hiciesemos el compilador nos daría un mensaje de error: “excepción no declarada”): /************************************ * Leo una cadena por teclado (el radio del círculo), la convierto a double * y calculo el area (PI*radio*radio) * El uso de las clases de entrada por teclado me obliga a: * 1- Uso de throws * 2- import java.io.* *************************************/ static void fun2() throws IOException { String c; Si no declaramos la excepción en el double radio; método y en todos los métodos que llamen a fun2, entonces el compilador /* Creo el objeto 'entrada', es un lector de entradas por teclado */ daría un mensaje de error: nos BufferedReader entrada = new BufferedReader( new InputStreamReader(System.in)); “excepción no declarada”): System.out.print( "Escriba el radio: " ); c = entrada.readLine(); // Leo un String de la entrada de teclado radio = Double.parseDouble( c ); // Convierto el String en double System.out.print( "El área es: " + 3.1416*radio*radio); } 8 Ejemplo • El ejemplo anterior declara la excepción IOException, pero no la captura ni gestiona • Además no gestionamos las excepciones debidas a entradas incorrectas por teclado (por ejemplo, cadena vacia o una cadena que no pueda convertir a número) • Si el usuario introduce por teclado una cadena vacía ocurriría una excepción: java.lang.NumberFormatException: empty String at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:986) at java.lang.Double.parseDouble(Double.java:202) • Para capturar las excepciones: try { /* Creo el objeto 'entrada', es un lector de entradas por teclado */ BufferedReader entrada = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Escriba el radio: "); c = entrada.readLine(); // Leo un String de la entrada de teclado radio = Double.parseDouble(c); // Convierto el String en double System.out.print("El área es: " + 3.1416 * radio * radio); } catch ( NumberFormatException e ) { System.out.print( "Error en el formato del número" ); } catch ( IOException e ) { System.out.print( "Error de entrada" ); } 9