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