32
Lenguaje de Programación I Ing. Gerald Basurco Zapata

EXCEPCIONES

Embed Size (px)

Citation preview

Page 1: EXCEPCIONES

Lenguaje de Programación I

Ing. Gerald Basurco Zapata

Page 2: EXCEPCIONES

• EXCEPCIONES

Page 3: EXCEPCIONES

¿Que es una Excepción?

Una situación que, aunque puede pasar, suele suponer algo negativo para la ejecución de nuestro programa.Ejemplos

◦ El usuario escribe una palabra cuando se esperaba un número.

◦ El programa intenta leer un fichero que no existe.◦ El programa no puede establecer una conexión de red.◦ Una conexión de red se pierde◦ El programa intenta realizar una división por cero.◦ Se intenta calcular la raíz cuadrada de un número

negativo.◦ El programa se sale de los límites de un array.◦ El programa accede a los miembros de un objeto

inexistente.

Page 4: EXCEPCIONES

Java y los Errores

En el lenguaje Java, una Excepción es un cierto tipo de error o una condición anormal que se ha producido durante la ejecución de un programa. Algunas excepciones son fatales y provocan que se deba finalizar la ejecución del programa. En este caso conviene terminar ordenadamente y dar un mensaje explicando el tipo de error que se ha producido. Otras, como por ejemplo no encontrar un fichero en el que hay que leer o escribir algo, pueden ser recuperables. En este caso el programa debe dar al usuario la oportunidad de corregir el error (indicando una nueva localización del fichero no encontrado).

Page 5: EXCEPCIONES

Gestión de errores

Un buen programa debe gestionar correctamente todas o la mayor parte de los errores que se pueden producir. Hay dos “estilos” de hacer esto:

◦ A la antigua: los métodos devuelven un código de error. Este código se chequea en el entorno que ha llamado al método con una serie de if elseif …, gestionando de forma diferente el resultado correcto o cada uno de los posibles errores. Este sistema resulta muy complicado cuando hay varios niveles de llamadas a los métodos.

◦ Con soporte en el propio lenguaje: En este caso el propio lenguaje proporciona construcciones especiales para gestionar los errores o Exceptions. Suele ser lo habitual en lenguajes modernos, como C++, Visual Basic y Java.

Page 6: EXCEPCIONES

Excepciones Estándar en Java

Para poder entender mejor los errores que pueden ocurrir en un programa, veamos un ejemplo: En el estudio de la clase String, mencionamos una función, que convierte un string en un número mediante la función estática Integer.parseInt.

public class app{ public static void main(String[] args) { String str=" 12 ";

int numero;numero=Integer.parseInt(str); System.out.println(numero);

}}

Page 7: EXCEPCIONES

Excepciones Estándar en Java

Si se introducen caracteres no numéricos, o no se quitan los espacios en blanco al principio y al final del string, se lanza una excepción NumberFormatException. El mensaje que aparece en la ventana nos indica el tipo de excepción

NumberFormatException,.

Page 8: EXCEPCIONES

Excepciones Estándar en Java

ArithmeticException

Las excepciones aritméticas son típicamente el resultado de una división por 0

NullPointerException

Se produce cuando se intenta acceder a una variable o método antes de ser definido. Se intento utilizar null donde se requería un objeto

ArrayIndexOutOfBoundsException

Se genera al intentar acceder a un elemento de un array más allá de los límites definidos inicialmente para ese array.

NumberFormatException

Se intento convertir una cadena con un formato inapropiado en un número.

Las excepciones más comunes son

Page 9: EXCEPCIONES

Excepciones Estándar en Java

Las excepciones en Java son objetos de clases derivadas de la clase base Exception. Existen también los errores internos que son objetos de la clase Error. Ambas clases Error y Exception son clases derivadas de la clase base Throwable.

Page 10: EXCEPCIONES

Excepciones Estándar en Java

Existe toda una jerarquía de clases derivada de la clase base Exception. Estas clases derivadas se ubican en dos grupos principales:

◦ Las excepciones en tiempo de ejecución (RuntimeException) ocurren cuando el programador no ha tenido cuidado al escribir su código. Por ejemplo, cuando se sobrepasa la dimensión de un array se lanza una excepción ArrayIndexOutOfBounds. Cuando se hace uso de una referencia a un objeto que no ha sido creado se lanza la excepción NullPointerException. Estas excepciones le indican al programador que tipos de fallos tiene el programa y que debe arreglarlo antes de proseguir.

◦ El segundo grupo de excepciones (IOException), es el más interesante, ya que indican que ha sucedido algo inesperado o fuera de control. Cubre las excepciones ocurridas al ejecutar una operación de entrada o salida. Este grupo de excepciones pertenece al paquete java.io.

Page 11: EXCEPCIONES

Excepciones Estándar en Java

La clase Error está relacionada con errores de compilación, del sistema o de la JVM. Estos errores son irrecuperables y no dependen del programador ni debe preocuparse de capturarlos y tratarlos.

Las excepciones que se lanzan durante la ejecución son excepciones implícitas y se corresponden con las subclases de RuntimeException y Error. Se dice que son implícitas porque son lanzadas por la maquina virtual de java y por lo tanto, los métodos implementados en las aplicaciones no tiene que declara que las lanza, y aunque lo hicieran, cualquier otro método que los invoque no esta obligado a manejarlas.

El resto de las excepciones, como las que corresponden con las subclases de IOException, son excepciones explicitas; esto significa que, si se quieren manipular, los métodos implementados en las aplicaciones tienen que declarar que las lanzan y en este caso, cualquier otro método que los invoque esta obligado a manejarlas.

Page 12: EXCEPCIONES

Manejo de Excepciones

Cuando un método se encuentra con una anomalía que no puede resolver, lo lógico es que lance (throw) una excepción, esperando que quien lo llamo directa o indirectamente la capture (catch) y maneje la anomalía. Incluso él mismo podría capturar y manipular dicha excepción. Si la excepción no se captura, el programa finalizara automáticamente.

Por ejemplo, se tienen la clase Leer, según se puede observar, el método dato de esta clase invoca a readLine con el propósito de devolver un objeto String correspondiente a la cadena leída. Según se ha explicado anteriormente, readLine puede lanzar una excepción de la clase IOException. Para manejarla hay que capturar, para lo cual se utiliza un bloque catch, y para poder capturarla hay que encerrar el código que puede lanzarla en un bloque try:

Page 13: EXCEPCIONES

Manejo de Excepciones

import java.io.*;class Leer{ public static String dato()

{ String sdato = " ";

try{

BufferedReader flujoE = new BufferedReader(new InputStreamReader(System.in));

sdato = flujoE.readLine();}catch(IOException e){

System.out.println("Error: " + e.getMessage());}return sdato;

}

}

Page 14: EXCEPCIONES

Manejo de Excepciones

Las palabras try y catch trabajan conjuntamente y pueden traducirse así: “poner a prueba un fragmento de código por si lanzara una excepción; si se ejecuta satisfactoriamente, continuar con la ejecución del programa; si no, capturar la excepción lanzada y manejarla”.

Las clases derivadas de Exception pueden pertenecer a distintos packages de Java. Algunas perenecen a java.lang (Throwable, Exception, RuntimeException, …); otras a java.io (EOFException, FileNotFoundException, ...) o a otros packages. Por heredar de Throwable todos los tipos de excepciones pueden usar los métodos siguientes:

◦ String getMessage() Extrae el mensaje asociado con la excepción.

◦ String toString() Devuelve un String que describe la excepción.

◦ void printStackTrace() Indica el método donde se lanzó la excepción.

Page 15: EXCEPCIONES

Lanzar Excepciones

Lanzar una excepción equivale a crear un objeto de la clase de la excepción para manipularlo fuera del flujo normal de ejecución del programa. Para lanzar una excepción se utiliza la palabra reservada throw y para crear un objeto, new. Por ejemplo, volviendo al método datos de la clase Leer expuesta anteriormente, si ocurre un error cuando se ejecute el método readLine se supone que éste ejecutara una sentencia similar a la siguiente:

If (error) throw new IOException();

Esta sentencia lanza una excepción de la clase IOException lo que implica crear un objeto de esta clase. Un objeto de estos contiene información acerca de la excepción, incluyendo su tipo y el estado del sistema cuando el error ocurrió.

Page 16: EXCEPCIONES

Lanzar Excepciones

Una vez lanzada la excepción, el sistema es responsable de encontrar a alguien que la capture con el objetivo de manipularla. El conjunto de esos “alguien” es el conjunto de métodos especificados en la pila de llamadas hasta que ocurrió el error.

Por ejemplo consideremos la siguiente aplicación, que invoca al método dato de la clase Leer con la intención de leer un dato:

public class test1{ public static void main( String[] args ) { String str; System.out.print("Dato: "); str = Leer.dato(); }}

Page 17: EXCEPCIONES

Lanzar Excepciones

Cuando se ejecute esta aplicación y se invoque al método dato, la pila de llamadas crecerá como se observa en al figura

Si al ejecutarse el método readLine ocurriera un error, según hemos visto anteriormente, este lanzaría una excepción de la clase IOException que interrumpirá el flujo normal de ejecución. Después, el sistema buscaría en la pila de llamadas hacia abajo y comenzando por el propio método que produjo el error, uno que implemente un manejador que pueda capturar esta excepción. Si el sistema, descendiendo por la pila de llamadas, no encontrara este manejador, el programa terminaria.

BufferedReader.readLineBufferedReader.readLine

Leer.datoLeer.dato

Test.mainTest.main

Page 18: EXCEPCIONES

Lanzar Excepciones

Para implementar un manejador para una clase de excepción hay que hacer las dos cosas que se indican a continuación:

1. Encerrar el código que puede lanzar la excepción en un bloque try. En la clase Leer presentada anteriormente, el método dato tiene un bloque try que encierra la llamada al método readLine, además de otras sentencias:

try{

//..sdato = flujoEreadLine();

}

Page 19: EXCEPCIONES

Lanzar Excepciones

2. Escribir un bloque catch capaz de capturar la excepción lanzada. En la clase Leer presentada anteriormente, el método dato tienen un bloque match capaz de capturar excepciones de la clase IOException y de sus subclases:

catch(IOException e){

System.out.println(“Error: ” + e.getMessage());}

Page 20: EXCEPCIONES

Lanzar Excepciones

En este manejador se observa un parámetro e que referencia al objeto que se creo cuando se lanzo la excepción capturada. Para manipularla, además de escribir el código que consideremos adecuado, disponemos de la funcionalidad proporcionada por la clase IOException, y la que podremos acceder mediante el objeto

Page 21: EXCEPCIONES

Lanzar Excepciones - Ejemplo

Del ejemplo presentado al principio de esta sesión, veamos como podemos solucionar los errores:

Page 22: EXCEPCIONES

Lanzar Excepciones - Ejemplo

Page 23: EXCEPCIONES

Lanzar Excepciones

Un manejador de excepción, catch, solo se puede utilizar a continuación de un bloque try o de otro manejador de excepción (bloque catch). Las palabras clave try y catch, por definición, van seguidas de un bloque que encierra el código relativo a cada una de ellas, razón por la cual es obligatorio utilizar llaves: {}.

El siguiente ejemplo muestra un manejador para una excepción de tipo EValorNoValido y otro para una excepción de tipo Exception:

Cuando una excepción es capturada se considera manejada, lo que significa que cualquier otro manejador existente no será tenido en cuenta.

…catch(EValorNoValido){

//Manejar de la excepción

EValorNoValido}catch(Exception e){

//Manejar de la excepción

cualquier otra excepción}

Page 24: EXCEPCIONES

Excepciones Derivadas

Cuando se trata de manejar excepciones, un bloque try puede estar seguido de uno o mas bloques catch, tantos como excepciones diferentes tengamos que manejar. Cada catch tendrá un parámetro de la clase Throwable, de alguna clase derivada de ésta, o bien de una clase de excepción definida por el usuario. Cuando se lance una excepción, el bloque catch que la capture será aquel cuyo parámetro sea de la clase de la excepción o de una superclase directa o indirecta. Debido a esto, el orden en el que se coloquen los bloques catch tiene que ser tal, que cualquiera de ellos debe permitir alcanzar el siguiente, de los contrario el compilador producirá un error.

Por ejemplo, si el primer bloque catch especifica un parámetro de la clase Throwable, ningún otro bloque que le siga podría alcanzarse; esto es, cualquier excepción lanzada seria capturada por ese primer bloque, ya que cualquier referencia a una subclase puede ser convertida implícitamente por Java en una referencia a su superclase directa o indirecta.

Page 25: EXCEPCIONES

Excepciones Derivadas

En cambio, en el ejemplo siguiente, una excepción de la clase EOFException será capturada por el primer bloque catch; una excepción de la clase IOException será capturada por el bloque segundo; una excepción de la clase FileNotFoundException, subclase de IOException, será capturada también por el bloque segundo; y una excepción de la clase ClassNotFoundException, subclase de la Exception, será capturada por el bloque tercero.

try{

//...}catch(EOFException e){

//Manejar esta clase de excepcion}catch(IOException e){

//Manejar esta clase de excepcion o de alguna de sus subclases

//excepto EOFException}catch(Exception e){

//Manejar esta clase de excepcion o de alguna de sus subclases

//excepto EOFException e IOException}

Page 26: EXCEPCIONES

Excepciones Derivadas

Page 27: EXCEPCIONES

Excepciones Propias

El lenguaje Java proporciona las clases que manejan casi cualquier tipo de excepción. Sin embargo, podemos imaginar situaciones en la que producen excepciones que no están dentro del lenguaje Java. Siguiendo el ejemplo anterior estudiaremos una situación en la que el usuario introduce un valor fuera de un determinado intervalo, el programa lanza un excepción, que vamos a llamar ExcepcionIntervalo.

Para crear y lanzar una excepción propia tenemos que definir la clase ExcepcionIntervalo derivada de la clase base Exception.

public class ExcepcionIntervalo extends Exception { public ExcepcionIntervalo(String msg) {

super(msg); } }

La definición de la clase es muy simple. Se le pasa un string msg, que contiene un mensaje, en el único parámetro que tiene el constructor de la clase derivada y éste se lo pasa a la clase base mediante super.

Page 28: EXCEPCIONES

Excepciones Propias

La función miembro que lanza una excepción tiene la declaración habitual que cualquier otro método pero se le añade a continuación la palabra reservada throws seguido de la excepción o excepciones que puede lanzar.

static void rango(int num, int den)throws ExcepcionIntervalo{ if((num>100)||(den<-5)){

throw new ExcepcionIntervalo("Números fuera del intervalo"); }

Cuando el numerador es mayor que 100 y el denominador es menor que 5 se lanza throw una excepción, un objeto de la clase ExcepcionIntervalo. Dicho objeto se crea llamando al constructor de dicha clase y pasándole un string que contiene el mensaje "Números fuera del intervalo".

Page 29: EXCEPCIONES

Excepciones Propias

Al programa que divide dos números, le añadimos la llamada a la función rango que verifica si los números están dentro del intervalo dado, y el bloque catch que captura la excepción que puede lanzar dicha función si los números no están en el intervalo especificado.

Page 30: EXCEPCIONES

Excepciones Propias

Hay otra alternativa para el ejercicio anterior, que es la de definir una función denominada calcular, que devuelva el cociente entre el numerador y el denominador, cuando se le pasa los strings obtenidos de los respectivos controles de edición. La función calcular, convierte los strings en números enteros, verifica el rango, calcula y devuelve el cociente entre el numerador y el denominador,

Page 31: EXCEPCIONES

Excepciones Propias

Vemos que la función calcular puede lanzar, throws, tres tipos de excepciones. En el cuerpo de la función se crea, new, y se lanza, throw, explícitamente un objeto de la clase ExcepcionIntervalo, definida por el usuario, e implícitamente se crea y se lanza objetos de las clases NumberFormatException y ArithmeticException definidas en el lenguaje Java.La sentencia que llama a la función calcular dentro del bloque try puede producir alguna de las tres excepciones que es capturada por el correspondiente bloque catch.

Page 32: EXCEPCIONES

Bloque Finally

El bloque finally {...} debe ir detrás de todos los bloques catch considerados. Si se incluye (ya que es opcional) sus sentencias se ejecutan siempre, sea cual sea el tipo de excepción que se produzca, o incluso si no se produce ninguna. El bloque finally se ejecuta incluso si dentro de los bloques try/catch hay una sentencia continue, break o return. La forma general de una sección donde se controlan las excepciones es por lo tanto:

El bloque finally es necesario en los casos en que se necesite recuperar o devolver a su situación original algunos elementos.