7 de julio de 2017

Especificación de excepciones lanzadas por un método.

   La mayoría de las veces, es más conveniente atrapar las excepciones que ocurren dentro un método; sin embargo, en otros casos lo mejor es que el método deje pasar la excepción para que algún manejador de excepciones, en algún otro nivel en la pila de invocación de métodos, se encargue de ella.

   Así por ejemplo, si se estuviera construyendo una clase Lista<T> (vea la entrada Listas (implementación)) como parte de un paquete de clases que conforman toda una gama de estructuras de datos, es poco probable que se puedan prever y anticipar todos los posibles escenarios y las necesidades de uso en los que su paquete de clases podría utilizarse.

   Es precisamente en este tipo de casos en los que sería mejor no atrapar la excepción dentro del método, y mejor permitir que éste lance a su vez la excepción para que sea atrapada por algún manejador de excepciones en algún otro nivel en la pila de invocación de métodos.

   El siguiente método atrapa y maneja dos posibles excepciones que podrían generarse:


      public void writeList( ) {
              PrintWriter out = null;

              try {
                  System.out.println("Entering try statement");
                  out = new PrintWriter(new FileWriter("OutFile.txt"));
        
                  for (int i = 0; i < SIZE; i++)
                      out.println("Value at: " + i + " = " + list.get(i));
              } catch (IndexOutOfBoundsException e) {
                  System.err.println("Caught IndexOutOfBoundsException: " +
                                       e.getMessage());
              } catch (IOException e) {
                  System.err.println("Caught IOException: " + e.getMessage( ));
              } finally {
                  if (out != null) {
                      System.out.println("Closing PrintWriter");
                      out.close();
                  } else {
                      System.out.println("PrintWriter not open");
                  }
              }
          }


   Si el método no atrapara las excepciones que pueden ocurrir dentro de él, entonces debe especificar que puede lanzar dichas excepciones:


      public void writeList( ) throws IOException, IndexOutOfBoundsException {
              PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));

              for (int i = 0; i < SIZE; i++) 
                  out.println("Value at: " + i + " = " + list.get(i));
              out.close();
      }


   Como IndexOutOfBoundsException es una excepción no verificada (unchecked exception), no es obligatorio incluirla en la cláusula throws, por lo que el método podría quedar como:


      public void writeList( ) throws IOException {
              PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));

              for (int i = 0; i < SIZE; i++) 
                  out.println("Value at: " + i + " = " + list.get(i));
              out.close();
      }


   De esta manera, la excepción tendrá que ser manejada en algún otro lado, en aquella parte del código en que haga uso del método writeList( ).

    Conviene en este momento al lector revisar el Ejercicio 4 de la entrada Ejercicios selectos, con la finalidad de ampliar su perspectiva al revisar un ejemplo adicional respecto a la especificación de excepciones lanzadas por un método.