martes, 8 de diciembre de 2015

Lanzamiento de excepciones

Las excepciones son lanzadas de manera automática por las rutinas que han sido identificadas en la biblioteca de clases de las API de Java para este fin.
Pero  el  programador  puede  lanzar  dichas  excepciones  utilizando  la  palabra reservada throw.
El  siguiente ejemplo muestra como se lanza una excepcion por parte del programador
import javax.swing.*;
import java.lang.*;
public class ejemplo2{
    public static int x[ ]= new int[10];

Fundamentos de programación orientada a objetos con Java
    public static int getElement(int i) throws ArrayIndexOutOfBoundsException { // Avisa que
                                               // Una excepción puede ocurrir en el método
        if(i>x.length)
            throw new ArrayIndexOutOfBoundsException( );  // Lanza la excepción
        return x[i];
    }
        public static void main(String [ ] args){
               
            try{
                System.out.println(getElement(20));
            }
            catch (ArrayIndexOutOfBoundsException AE){
                System.err.println("Error indice fuera de rango");
            }
        }
}
Como  se  puede  observar  el  formato  para  lanzar  una  excepción  es  el siguiente:
throw   new claseException ( );
claseException es el nombre de la clase que tenemos que crear un objeto para lanzar la excepción.
La palabra throw requiere por fuerza un objeto Throwable o descendiente de el. El objeto que se cree y se lance con throw debe ser de la misma clase que espera alguna de las clausulas catch despues de la clausula try.

Excepciones mas comunes

Cada lenguaje define sus propias exceciones,  el  caso particular  de Java,
ofrece una jerarquia de clases para el  manejo de excepciones,  se inicia con la
clase java.lang.Throwable de la cual se desprenden las clases  java.lang.Error y
java.lang.Exception.
Cada paquete implementa las excepciones para manejar cuestiones propias
que ocurren en cada clase que conforman un paquete,  algunas excepciones se
muestran a continuación:

java.lang ArithmeticException
Ocurre   cuando   una   operación aritmetica   no   puede   ocurrir   por sobreflujo, división por cero, etc.

java.lang ArrayIndexOutOfBoundsException
Ocurre cuando se intenta acceder a  posiciones  fuera  del   limite  de un arreglo.

java.lang ClassNotFoundException
Ocurre   cuando   una   aplicación intenta  cargar   una  clase  y  no  la localiza.

java.lang NullPointerException
Ocurre cuando se intenta acceder a   un   elemento   de   un   arreglo cuando  no  se  ha  creado  o  a un objeto que tiene el valor de null.

java.lang NumberFormatException
 Ocurre   cuando   se   intenta convertir   de   una   cadena   a   un valor   numérico  y  no  esta   en  el
formato apropiado.

java.io EOFException
Ocurre   cuando   se   intenta   leer desde   un   archivo   o   desde   un flujo   de   entrada   cuando   se
encuentra en el fin del archivo.

java.io IOException
 Ocurre cuando una operacion de lectura/escritura   no   se   pudo llevar a cabo correctamente

Throw

Con la claúsula throws indicamos todas las excepciones que no serán manejadas
dentro del método, sino por el método que la llama. Estas excepciones podrán ser
errores del programa como los vistos anteriormente, o bien, generados de forma
explícita con throw.

 La sintáxis de throw es la siguiente:

throw <ObjetoThrowable>;

El <ObjetoThrowable> es un objeto de clase Throwable o alguna de sus
subclases. Tenemos dos opciones de obtener este objeto:
• Si estamos dentro de un bloque catch, el parámetro (<TipoExcepción>).
• Si estamos fuera de los bloques catch, dentro del código propiamente dicho
de un método, crearlo con el operador new.

Al ejecutarse una sentencia throw, la ejecución salta al bloque catch
correspondiente, de la misma forma que si se hubiera producido el error de forma
natural.

Ventajas:


• Una clase informa de las posibles situaciones anómalas de la clase.
• Esas excepciones tendrá que redefinir el método que llame a este método de forma
obligatoria. Esto nos permite decidir las acciones a tomar en caso de que se
produzcan. El método que llama, o cualquier otro por encima en la pila de llamadas.

Por ejemplo, el método "FileWriter" se ha definido:

 public FileWriter (String name) throws IOException {
  // ...
 }


Si utilizamos el método "FileWriter" definido así, deberemos capturar la
excepción "IOException" de forma obligatoria. Así podemos decidir lo que hacer en el
caso de que se produzca un error de ese tipo.

Programacion y Generalizacion

El <TipoExcepción> es un objeto que se instancia a partir de la clase correcta
(Throwable o alguna de sus subclases), justo en el momento de producirse el error, y
contiene información de la excepción producida.

Programación avanzada    
 En la estructura jerárquica de la librería de clases de Java, tenemos las clases que
implementan cada uno de los distintos tipos de error:

Java.lang.Throwable
  Exception
   RuntimeException
    ArithmeticException
    NullPointerException
    NumberFormatException
    ArrayIndexOutOfBoundsException
   ClassNotFoundException
   IOException
    EOFException
  Error

 La clase raíz es Throwable, la cual tiene dos subclases que clasifican los dos
grupos de tipos error posibles:

 Exception: son los errores habituales, capturables por el usuario. De esta
clase se derivan otras subclases, e incluso podemos derivar nosotros nuestras
propias clases.

 Error: son errores graves, en los que conviene no capturar su excepción y
dejar que aborte el programa de forma anormal. Suelen ser errores de
ejecución de la JVM.

Cuando se produce un error, se mira si hay una manejador para dicha excepción
en el método donde se ha producido. Si no se captura la excepción, se va retornando en
la pila de llamadas, hasta llegar a la función main() si no se hubiese capturado en
ninguna las funciones o métodos. Si en esta función tampoco se captura la excepción, se
ejecutará el manejador de excepciones por defecto, que consiste en abortar el
programa mostrando un mensaje significativo del error y el lugar donde se ha producido
(clase, método, número de línea, pila de llamadas, etc.).

 Cuando utilizamos las clases de Java (o nuestras), hay métodos que lanzan una
excepción (throw). Dependiendo del tipo de excepción estaremos obligados a capturar
la excepción generada o no. Por esto, debemos distinguir dos tipos de excepciones:

• Excepciones implícitas: no estamos obligados a capturarlas.
Son todas las de RuntimeException y Error.

• Excepciones explícitas: si estamos obligados a capturarlas.
Son ClassNotFoundException, IOException y EOFException.


Generación de errores
Programación avanzada    

 Otra posibilidad que tenemos en la gestión de errores es provocarlos de forma
explícita. Para ello utilizaremos las palabras clave: throw y throws.

 Vimos que la declaración de un método tenía la siguiente sintáxis:

[<Modif. método>] <TipoRetorno> <NombreMetodo> ( [<ListaParámetros>] ) [throws <Excepciones>]
{
 // Variables locales
 ...
 // Instrucciones o sentencias
 ...
 return (<Expresión>);
}


Excepciones en java

Cuando se produce algún error durante la ejecución de un programa, el intérprete
Java aborta su ejecución, mostrando un mensaje. Java dispone de unas sentencias para
poder capturar los errores en tiempo de ejecución, pudiendo nosotros decidir la acción a
realizar en el caso de que se produzca un error, y sin que se detenga la ejecución del
programa.

 Se trata de las sentencias de manejo de excepciones: try ... catch ... finally.

try {
<Bloque de sentencias a supervisar>
}
catch ( <TipoExcepcion> ) {
<Bloque de sentencias a ejecutar en caso de error>
}
finally {
<Bloque de sentencias a ejecutar en caso de error por defecto>
}

 La ventaja de estas sentencias es que separamos de forma explícita el código
que gestiona los errores del código del programa propiamente dicho, obteniendo un
código más claro que si utilizásemos sentencias de tipo: if, switch, etc. Además, el
código se ejecutará de forma más eficiente, ya que no tendremos que estar
continuamente comprobando condiciones que no son muy frecuentes o “imposibles”.