Try-Catch y Manejo de Errores

Try-Catch

El bloque "try-Catch" castenillando las palabras "intentar sino atrapar" es un bloque de declaración encerrado entre llaves{} como cualquier otro donde en nuestro try incluimos declaraciones que "pueden" ocacionar errores en tiempo de compilación es decir que nuestro codigo no se encuentra mal escrito, y por eso le pedimos que "Intente" hacerlo sino que atrape lo que declaramos en nuestro "catch".
Podemos usarlo donde queramos pero el sentido es hacerlo cuando sabemos o sospechamos que nuestras declaraciones puedan ocacionar algún error como cargar ficheros y la ruta pueda no estar disponible.
Nuestro "try" se ejecuta normalmente hasta el momento que se encuentre un error, y desde esa linea "salta" a el bloque catch y no le importa las declaraciones siguientes.
Podemos incluir tantos "catchs" como excepciones querramos.

Un ejemplo básico sería mostrar un indice de un array que este fuera del límite del mismo, es decir declaramos un arreglo que contenga "x" variables y le pedimos mostrar "x+1" que no lo va a encontrar. En ese momento al no poder "intentar" mostrar un indice que se no encuentra deja de ejecutar nuestro bloque try para ejecutar el bloque catch.
  1. public class IntentarAtrapar {
  2.     public static void main(String[] args) {
  3.         int numeros[] = {1,2,3,4,5};
  4.        
  5.         try{
  6.             System.out.println(numeros[5]);
  7.         }catch (Exception e){
  8.             System.out.println(e);
  9.         }
  10.     }
  11. }
El resultado será que el indice 5 (en arrays empezamos a contar desde cero) no esta declarado y como resultado solo se ejecuta el bloque catch
  • java.lang.ArrayIndexOutOfBoundsException: 5
Al mostrar nuestra "e" nos menciona la clase java para el error ocacionado y el n° del indice que intentamos acceder, en conclución "Excepción fuera de los límites del arreglo: 5" nos da la pista que ese indice no está declarado.

Finally

El bloque "finally" (Finalmente) es opcional a nuestro try/catch. La funcionalidad es que este bloque se ejecutara en cualquiera de los casos, es decir si ocurre una ecepción o no siempre se ejecuta este bloque al final.
La utilidad de contar con este bloque se da por ejemplo al abrir un flujo de datos en nuestro try, donde al final del mismo lo cerrariamos pero si ocurre una excepción esta queda salteada, entonces usaremos este bloque para cerrar ese flujo porque sabemos que se ejecuta de todos modos.

Si modificamos un poquito nuestro ejemplo anterior, no tendriamos un error y por último nuestra declaración "finally"
  1. public class IntentarAtrapar {
  2.     public static void main(String[] args) {
  3.         int numeros[] = {1,2,3,4,5};
  4.        
  5.         try{
  6.             System.out.println(numeros[2]);
  7.         }catch (Exception e){
  8.             System.out.println(e);
  9.         }finally{
  10.             System.out.println("El bloque finally se ejecuta siempre");
  11.         }
  12.     }
  13. }
El resultado será:
  • 3
  • El bloque finally se ejecuta siempre

Errores y Excepciones

Los Errores y excepciones son los mecanismos por el cual podemos hacer frente a distintos incovenientes que pueden o no surgir y que pueden ser dados por razón lógica del programa como un índice fuera de rango, dividir por cero o errores creados a partir de ciertos objetos como cargar archivos o URL de páginas web que pueden estar mal escrita la ruta o no estar disponibles.
Existe toda una jerarquia de Clases Java para el manejo de errores a partir de la Clase Throwable, sus hijas Error y Exception, la clase RunTimeException entre muchas otras.

Throws y Throw

Otra manera de manejar excepciones en java es la de "Lanzar" las misma, es decir no tratamos de ninguna forma, para que SI lo haga quien lo llame.

Para los lanzamientos de excepciones usamo dos palabras claves throws y throw.
  • Throws (Con S) se utiliza en la firma de los métodos para anunciar que en el mismo se pueden dar errores y que deben ser tratados.
  • Throw (Sin S) se utiliza en el catch, una vez atrapado, para lanzar la excepción para quien nos llame.

La declaración throw (lanzar) sirve para manejar nuestros errores o excepciones simplemente de la manera más facil que es no haciéndose cargo del error sino que además lo lanza para que quién lo tome se encargue de el como es debido (lo atrape).
*En el mismo ejemplo reformado, genero mi array y el try-catch dentro de un método de instancia pero el catch solo lanza la excepción, luego desde el main un objeto hace la llamada al método desde otro try-catch pero esta mostrar un mensaje que se produce un error.
  1. public class IntentarAtrapar {
  2.     public void mostrar(){
  3.         int numeros[] = {1,2,3,4,5};
  4.        
  5.         try{
  6.             System.out.println(numeros[5]);
  7.         }catch (Exception e){
  8.             throw e;
  9.         }
  10.     }
  11.     public static void main(String[] args) {
  12.         IntentarAtrapar objeto = new IntentarAtrapar();
  13.         try{
  14.             objeto.mostrar();
  15.         }catch(Exception e){
  16.             System.out.println("Lo sentimos, ha ocurrido un error.");
  17.         }
  18.     }
  19. }
La salida de este códgio es:
  • Lo sentimos, ha ocurrido un error.

La declaración throws se utliza en la firma de nuestro método para alertar que nuestras declaraciones pueden ocacionar errores y que estos deben ser tratados. Si nadie captura la excepción interviene un manejador por defecto que normalmente imprime información que ayuda a encontrar quién produjo la excepción.
  1. public cargarURL(String direccionPagina) throws MalFormedURLException{
  2.     URL miPagina = new URL(direccionPagina);
  3.     loadWebPage(miPagina);
  4. }
*En este otro ejemplo intentamos hacer una división que tendrá 2 excepciones la cuales son ingresar un valor no-entero y la de dividir por cero. Para lo cual lo vamos a hacer dentro un método el cual avisa que se puede producir este error con la declaración throws
  1. import java.util.InputMismatchException;
  2. import java.util.Scanner;
  3. public class DividirCero {
  4.    
  5.     public static int cociente( int numerador, int denominador ) throws ArithmeticException {
  6.        
  7.         return numerador / denominador; // posible división entre cero
  8.     }
  9.    
  10.     public static void main(String args[]) {
  11.         System.out.println("*******************************");
  12.         System.out.println("División de números de enteros:");
  13.         System.out.println("*******************************");
  14.        
  15.         Scanner miScanner = new Scanner( System.in );
  16.         boolean ciclo = true;  
  17.        
  18.         do{
  19.             try {
  20.                 System.out.print("\nIntroduzca un numerador entero: ");
  21.                 int numerador = miScanner.nextInt();
  22.                
  23.                 System.out.print("Introduzca un denominador entero: ");
  24.                 int denominador = miScanner.nextInt();
  25.                
  26.                 int resultado = numerador / denominador;
  27.                
  28.                 System.out.print("Resultado: " + numerador + " dividido entre " + denominador + " = " + resultado);
  29.                 ciclo = false;
  30.                
  31.             } catch ( InputMismatchException e) {          
  32.                 System.err.println("\nExcepcion: " e);
  33.                 miScanner.nextLine(); //descarta la entrada previa       
  34.                 System.out.println("Debe introducir enteros. Intente de nuevo.\n" );
  35.                
  36.                
  37.             } catch ( ArithmeticException aE){
  38.                 System.err.println("\nExcepcion: " aE);
  39.                 System.out.println( "Cero es un denominador invalido. Intente de nuevo.\n" );
  40.             }
  41.         } while ( ciclo );
  42.     }
  43.    
  44.  }
El resultado será:

No hay comentarios:

Publicar un comentario