Sei sulla pagina 1di 11

Curso de Java

TEMA 8
Excepciones en Java
Manejo de Excepciones
Cuando un programa Java viola las restricciones semnticas del lenguaje (se produce un error), la mquina virtual Java comunica este hecho al programa mediante una excepcin. La aplicacin Java no debe morir y generar un core (o un crash en caso del DOS), al contrario, se lanza (throw) una excepcin y se captura (catch) para resolver esa situacin de error. Muchas clases de errores pueden provocar una excepcin, desde un desbordamiento de memoria o un disco duro estropeado hasta un disquete protegido contra escritura, un intento de dividir por cero o intentar acceder a un vector fuera de sus lmites. Cuando esto ocurre, la mquina virtual Java crea un objeto de la clase exception o error y se notifica el hecho al sistema de ejecucin. Se dice que se ha lanzado una excepcin (Throwing Exception). Un mtodo se dice que es capaz de tratar una excepcin (Catch Exception) si ha previsto el error que se ha producido y prev tambin las operaciones a realizar para recuperar el programa de ese estado de error. En el momento en que es lanzada una excepcin, la mquina virtual Java recorre la pila de llamadas de mtodos en busca de alguno que sea capaz de tratar la clase de excepcin lanzada. Para ello, comienza examinando el mtodo donde ese ha producido la excepcin; si este mtodo no es capaz de tratarla, examina el mtodo desde el que se realiz la llamada al mtodo donde se produjo la excepcin y as sucesivamente hasta llegar al ltimo de ellos. En caso de que ninguno de los mtodos de la pila sea capaz de tratar la excepcin, la mquina virtual Java muestra un mensaje de error y el programa termina. Los programas escritos en Java tambin pueden lanzar excepciones explcitamente mediante la instruccin throw, lo que facilita la devolucin de un cdigo de error al mtodo que invoc el mtodo que caus el error. Veamos un ejemplo.
Jess Cceres Tello Pg. 1 - 11

Curso de Java

public class Excepciones1 { public static void main(String[] arg) { metodo(); } static void metodo() { int divisor = 0; int resultado = 100/divisor; System.out.println(Resultado: + resultado); System.out.println(Una Suma: + (3+4)); }

Ejemplo 8.1: Lanzando una excepcin

Si intentamos ejecutar este programa obtendremos el siguiente resultado:

Lo que ha ocurrido es que la mquina virtual Java ha detectado una condicin de error y ha creado un objeto de la clase java.lang.ArithmeticException. Como el mtodo donde se ha producido la excepcin no es capaz de tratarla, se trata por la mquina virtual Java, que muestra el mensaje de error anterior y finaliza la ejecucin del programa.

Generacin de Excepciones en Java


Partiendo de la base de que cualquier mtodo puede lanzar excepciones en Java, es aconsejable tener declaradas todas las posibles excepciones que se puedan generar en dicho mtodo, para lo cual se utilizar la clusula throws de la declaracin de mtodos. Para que se pueda lanzar una excepcin es necesario crear un objeto de tipo Exception o alguna de sus subclases como ArithmeticException y lanzarlo mediante la instruccin throw como se muestra en el siguiente ejemplo:

Jess Cceres Tello

Pg. 2 - 11

Curso de Java

class LanzaExcepcion { public static void main(String argumentos[]) throws ArithmeticException { int i=1, j=2; if (i/j< 1) throw new ArithmeticException(); else System.out.println(i/j); } } Ejemplo 8.2: Lanzamiento de una excepcin desde el mtodo main de una clase

Jerarqua de clases de las excepciones en Java

Jess Cceres Tello

Pg. 3 - 11

Curso de Java

Un grfico un poco ms claro de esta jerarqua de clases

Captura de Excepciones
Un manejador de excepciones es una porcin de cdigo que se va a encargar de tratar las posibles excepciones que se puedan generar. En Java, de forma similar a C++ se pueden tratar las excepciones previstas por el programador utilizando unos mecanismos, los manejadores de excepciones, que se estructuran en tres bloques: El bloque try El bloque catch El bloque finally (no existente en C++)

El bloque try Lo primero que hay que hacer para que un mtodo sea capaz de tratar una excepcin generada por la mquina virtual Java es encerrar las instrucciones susceptibles de generarla en un bloque try.
Jess Cceres Tello Pg. 4 - 11

Curso de Java

try { } Bloque de Instrucciones

Cualquier excepcin que se produzca dentro del bloque try ser analizado por el bloque o bloques catch que se ver en el punto siguiente. En el momento en que se produzca la excepcin, se abandona el bloque try y, por lo tanto, las instrucciones que sigan al punto donde se produjo la excepcin no sern ejecutadas. Cada bloque try debe tener asociado al menos un bloque catch El bloque catch Por cada bloque try pueden declararse uno o varios bloques catch, cada uno de ellos capaz de tratar un tipo u otro de excepcin.

try { Bloque de Instrucciones } catch (TipoExcepcin nombreVariable) { Bloque de Instrucciones del primer catch } catch (TipoExcepcin nombreVariable) { Bloque de Instrucciones del segundo catch } ...

Para declarar el tipo de excepcin que es capaz de tratar un bloque catch, se declara un objeto cuya clase es la clase de la excepcin que se desea tratar o una de sus superclases. Vemoslo con un ejemplo:
class ExcepcionTratada { public static void main(String[] arg) { int i=5; j=0; try { int k=i/j; System.out.println(Esto no se va a ejecutar); }catch (ArithmeticException ex) { System.out.println(Has intentado dividir por cero); } System.out.println(Fin del programa); } }

Ejemplo 8.3: Clase que captura la excepcin producida por una divisin por 0

Jess Cceres Tello

Pg. 5 - 11

Curso de Java

Cuando se intenta dividir por cero, la mquina virtual Java genera un objeto de la clase ArithmeticException. Al producirse la excepcin dentro de un bloque try, la ejecucin del programa se pasa al primer bloque catch. Si la clase de la excepcin se corresponde con la clase o alguna subclase de la clase declarada en el bloque catch, se ejecuta el bloque de instrucciones catch y a continuacin se pasa el control del programa a la primera instruccin a partir de los bloques try-catch. Como puede verse, tambin se podra haber utilizado en la declaracin del bloque catch, una superclase de la ArithmeticException. Por ejemplo:
... catch (RuntimeException ex) { ... o ... catch (Exception ex) { ...

Sin embargo, es mejor utilizar excepciones lo ms cercanas al tipo de error previsto, ya que lo que se pretende es recuperar al programa de alguna condicin de error y si se meten todas las condiciones en el mismo saco, seguramente habr que averiguar despus qu condicin de error se produjo para poder dar una respuesta adecuada.

El bloque finally El bloque finally se utiliza para ejecutar un bloque de instrucciones sea cual sea la excepcin que se produzca. Este bloque se ejecutar en cualquier caso, incluso si no se produce ninguna excepcin. Sirve para no tener que repetir cdigo en el bloque try y en los bloques catch
... try {

Bloque de Instrucciones del try } catch (TipoExcepcin nombreVariable) { Bloque de Instrucciones del primer catch } catch (TipoExcepcin nombreVariable) { Bloque de Instrucciones del segundo catch } ..... }finally { Bloque de Instrucciones de finally }

Jess Cceres Tello

Pg. 6 - 11

Curso de Java

Creacin de Excepciones
Se pueden definir excepciones propias en Java, no hay por qu limitarse a las predefinidas, bastar con que la clase extienda de la clase Exception y proporcionar la funcionalidad extra que requiera el tratamiento de esa excepcin. Por ejemplo, consideremos un programa cliente/servidor. El cdigo cliente se intenta conectar al servidor, y durante 5 segundos se espera a que conteste el servidor. Si el servidor no responde, el servidor lanzara la excepcin de time-out:
class ServerTimeOutException extends Exception {} public void conectame( String nombreServidor ) throws Exception { int exito; int puerto = 80; exito = open( nombreServidor,puerto ); if( exito == -1 ) throw ServerTimeOutException; }

Ejemplo 8.4: Mtodo que lanza una excepcin no definida (Exception)

Si se quieren capturar las propias excepciones, se deber utilizar la sentencia try:


public void encuentraServidor() { ... try { conectame( servidorDefecto ); catch( ServerTimeOutException e ) { System.out.println( "Time-out del Servidor, intentando alternativa", 5,5 ); conectame( servidorAlterno ); } ... }

Cualquier mtodo que lance una excepcin tambin debe capturarla, o declararla como parte de la interface del mtodo. Cabe preguntarse entonces, el porqu de lanzar una excepcin si hay que capturarla en el mismo mtodo. La respuesta es que las excepciones no simplifican el trabajo del control de errores. Tienen la ventaja de que se puede tener muy localizado el control de errores y no tenemos que controlar millones de valores de retorno, pero no van ms all.

Jess Cceres Tello

Pg. 7 - 11

Curso de Java

Todos los mtodos Java utilizan la sentencia throw para lanzar una excepcin. Esta sentencia requiere un slo argumento (un objeto Throwable) Veamos el siguiente cdigo de la funcin pop() cuyo propsito es sacar el elemento superior de la pila.

public Object pop() throws EmptyStackException { Object obj; if (size == 0) throw new EmptyStackException(); obj = objectAt(size - 1); setObjectAt(size - 1, null); size--; return obj; } Ejemplo 8.5: Otro mtodo lanzando una excepcin de tipo Pila vaca

El mtodo pop() comprueba si la pila no est vaca. Si lo est, crea un nuevo objeto de la clase EmptyStackException y lo lanza, aunque en el mtodo no se genere alguna excepcin debido a lo bien validado que se encuentra, nosotros somos quienes lo lanzamos. Adems por lgica, la clase EmpyStackException es una subclase de Thowable, ya que en cualquier otro caso, no se podra lanzar dicha excepcin. Algo que se debe considerar aqu, es que en la declaracin del procedimiento aade el siguiente cdigo throws EmptyStackException, throws es una palabra reservada de java, y EmpyStackException es una subclase de Throwable. El uso de throws permite evitarnos la molestia de capturar las excepciones del tipo de excepciones indicadas despus de esta palabra (las clases van separadas por coma), esto debido a que deja al sistema de ejecucin Java que decida cul sera la mejor opcin en caso de que ocurriera una excepcin de los tipos indicados. Para crear una clase de tipo Throwable tan solo hay que hacerla heredar de una clase del tipo Exception o subclases de ella y definir el constructor con un mensaje de entrada:
public class DividePorCeroException extend ArithmeticException { public DividePorCeroException (String mensaje) { super(mensaje); }

De esta forma cualquier clase puede lanzar este tipo de excepcin:


public double divider(int num, int den) throws DividePorCeroException { if (den==0) throw new DividePorCero(Error, ests dividiendo por cero.); return ((double) num/(double) den);

Jess Cceres Tello

Pg. 8 - 11

Curso de Java

Laboratorio
Este programa lee un fichero (fichero.txt), y lee su contenido en forma de nmeros. Si alguno de los nmeros ledos es negativo, lanza una excepcin MiExcepcion, Adems gestiona la excepcin IOException, que es una excepcin de las que Java incluye y que se lanza si hay algn problema en una operacin de entrada/salida. Ambas excepciones son gestionadas, imprimiendo su contenido (cadena de error) por pantalla.
// Creo una excepcin personalizada class MiExcepcion extends Exception { MiExcepcion(){ super(); // constructor por defecto de Exception } MiExcepcion( String cadena ){ super( cadena ); // constructor param. de Exception } } // Esta clase lanzar la excepcin class Lanzadora { void lanzaSiNegativo( int param ) throws MiExcepcion { if ( param < 0 ) throw new MiExcepcion( "Numero negativo" ); } } class Excepciones { public static void main( String[] args ) { // Para leer un fichero Lanzadora lanza = new Lanzadora(); FileInputStream entrada = null; int leo; try { entrada = new FileInputStream( "fich.txt" ); while ( ( leo = entrada.read() ) != -1 ) lanza.lanzaSiNegativo( leo ); entrada.close(); System.out.println( "Todo fue bien" ); } catch ( MiExcepcion e ){ // Personalizada System.out.println( "Excepcion: " + e.getMessage() ); } catch ( IOException e ){ // Estndar System.out.println( "Excepcion: " + e.getMessage() ); } finally { if ( entrada != null ) try { entrada.close(); // Siempre queda cerrado } catch ( Exception e ) { System.out.println( "Excepcion: " + e.getMessage() ); } System.out.println( "Fichero cerrado." ); } } }

Jess Cceres Tello

Pg. 9 - 11

Curso de Java

La salida de este programa, suponiendo un nmero negativo sera: Excepcion: Numero negativo Fichero cerrado En el caso de que no hubiera ningn nmero negativo sera: Todo fue bien Fichero cerrado En el caso de que se produjese un error de E/S, al leer el primer nmero, sera: Excepcion: java.io.IOException Fichero cerrado

Jess Cceres Tello

Pg. 10 - 11

Curso de Java

Ejercicios
Construir una aplicacin que mediante el uso de excepciones diseadas por el programa identifique el nmero de parmetros que se pasan a la aplicacin en su llamada por teclado. Para ello se disearn tres tipos de excepciones, para uno, dos o ms parmetros. Construir una jerarqua de clases de excepciones que identifiquen si el/los parmetros pasados son nmeros o letras. Si son nmeros se proceder a su divisin y si el segundo parmetro fuese 0 se identificar este hecho mediante el lanzamiento de su excepcin correspondiente.

Jess Cceres Tello

Pg. 11 - 11

Potrebbero piacerti anche