5-Excepciones

26
EXCEPCIONES EXCEPCIONES

description

Apunte sobre excepciones en Java

Transcript of 5-Excepciones

EXCEPCIONESEXCEPCIONES

Las excepciones proporcionan una forma Las excepciones proporcionan una forma clara de comprobar posibles errores sin clara de comprobar posibles errores sin oscurecer el código.oscurecer el código.

Las excepciones convierten las condiciones Las excepciones convierten las condiciones de error que un método puede señalar en una de error que un método puede señalar en una parte explícita del contrato del método. La parte explícita del contrato del método. La lista de excepciones pueden ser vistas por el lista de excepciones pueden ser vistas por el programador, comprobada por el compilador programador, comprobada por el compilador y preservada (si es necesario) por las clases y preservada (si es necesario) por las clases extendidas que redefinan el método.extendidas que redefinan el método.

Creación de tipos de Creación de tipos de excepciónexcepción

Las excepciones son objetos.Las excepciones son objetos.

Todos los tipos de excepción (las clases) Todos los tipos de excepción (las clases) deben extender de la clase deben extender de la clase ThrowableThrowable o de o de una de sus subclases.una de sus subclases.

Por convenio, los nuevos tipos de excepción Por convenio, los nuevos tipos de excepción extienden a extienden a ExceptionException, una subclase de, una subclase de ThrowableThrowable

Excepciones Excepciones comprobadascomprobadas

El compilador comprueba que nuestros El compilador comprueba que nuestros métodos lanzan sólo las excepciones que métodos lanzan sólo las excepciones que ellos mismos han declarado que pueden ellos mismos han declarado que pueden lanzar.lanzar.

Representan condiciones que, aunque Representan condiciones que, aunque excepcionales, se puede esperar excepcionales, se puede esperar razonablemente que ocurran, y si ocurren razonablemente que ocurran, y si ocurren deben ser consideradas de alguna forma.deben ser consideradas de alguna forma.

Excepciones no Excepciones no comprobadascomprobadas

Las excepciones no comprobadas Las excepciones no comprobadas representan condiciones que reflejan errores representan condiciones que reflejan errores en la lógica de nuestro programa de los que en la lógica de nuestro programa de los que no es posible recuperarse de forma razonable no es posible recuperarse de forma razonable en ejecución.en ejecución.

Extendiendo Extendiendo ExceptionException

Algunas veces es útil tener más datos para Algunas veces es útil tener más datos para describir la condición excepcional, además de describir la condición excepcional, además de la cadena de texto que proporciona la cadena de texto que proporciona ExceptionException. En estos casos se puede . En estos casos se puede extender a extender a ExceptionException creando una clase creando una clase que contenga los datos añadidos.que contenga los datos añadidos.

EjemploEjemploSupongamos que se añade un método Supongamos que se añade un método sustituirValorsustituirValor a la interfaz a la interfaz AtribuidoAtribuido (Cap.4). Este método sustituye el valor actual (Cap.4). Este método sustituye el valor actual de un atributo con nombre por un nuevo de un atributo con nombre por un nuevo valor. Si dicho atributo con nombre no existe, valor. Si dicho atributo con nombre no existe, se debería lanzar una excepción.se debería lanzar una excepción.

Esa excepción debería contener el nombre Esa excepción debería contener el nombre del atributo. Se crea la clase del atributo. Se crea la clase NoTalAtributoExceptionNoTalAtributoException::

public class NoTalAtributoException extends Exceptionpublic class NoTalAtributoException extends Exception

{{

public String nombreAtrib;public String nombreAtrib;

public NoTalAtributoException(String nombre)public NoTalAtributoException(String nombre)

{{

super(“El atributo con el nombre \”” + nombre +super(“El atributo con el nombre \”” + nombre +

““\ ” no se encuentra”);\ ” no se encuentra”);

nombreAtrib = nombre;nombreAtrib = nombre;

}}

}}Toma el nombre del atributoToma el nombre del atributo

Almacena el dato en un campo públicoAlmacena el dato en un campo público

Invoca al constructor de la superclase con una descripción en forma de cadena de Invoca al constructor de la superclase con una descripción en forma de cadena de texto de lo que ha sucedido.texto de lo que ha sucedido.

Almacena una descripción de la causa del error comprensible para las personas y Almacena una descripción de la causa del error comprensible para las personas y los datos que crearon el errorlos datos que crearon el error

Las excepciones se capturan de acuerdo con Las excepciones se capturan de acuerdo con su tipo.su tipo.

Se pueden capturar en forma clasificada, Se pueden capturar en forma clasificada, diferenciandolas de otras excepciones.diferenciandolas de otras excepciones.

Lanzamiento de Lanzamiento de excepcionesexcepciones

Las excepciones se lanzan utilizando la Las excepciones se lanzan utilizando la sentencia sentencia throwthrow..

throw throw expresiónexpresión

Donde Donde expresiónexpresión es una referencia a un es una referencia a un objeto objeto Throwable.Throwable.

Se amplia el método Se amplia el método sustituirValorsustituirValor de de la clase la clase ImplAtribuidoImplAtribuido

public void sustituirValor(String nombre, Object nuevoValor) public void sustituirValor(String nombre, Object nuevoValor) throwsthrows NoTalAtributoException NoTalAtributoException

{{

Atrib atrib = buscar(nombre);Atrib atrib = buscar(nombre); //busca el atributo //busca el atributo

if(atrib == null)if(atrib == null)

throwthrow new NoTalAtributoException(nombre); new NoTalAtributoException(nombre);

atrib.setValor(nuevoValor);atrib.setValor(nuevoValor);

}}

Si se lanza la excepción no se regresa al flujo normal de Si se lanza la excepción no se regresa al flujo normal de programa.programa.

Las excepciones son objetos, por lo tanto deben crearse Las excepciones son objetos, por lo tanto deben crearse antes de lanzarse.antes de lanzarse.

Transferencia de controlTransferencia de control

Una vez que se produce una excepción, las Una vez que se produce una excepción, las acciones que hubiera detrás del punto donde acciones que hubiera detrás del punto donde la excepción se produjo no tiene lugar. La la excepción se produjo no tiene lugar. La siguiente acción que ocurrirá estará o en un siguiente acción que ocurrirá estará o en un bloque bloque finallyfinally o en un bloque o en un bloque catchcatch que que capture la excepcióncapture la excepción

La cláusula La cláusula throwsthrowsDeclara las excepciones comprobadas que puede Declara las excepciones comprobadas que puede lanzar un método.lanzar un método.

Son tan importante como el tipo de valor que Son tan importante como el tipo de valor que devuelve.devuelve.

Se pueden declarar varias, separadas por comas. Se pueden declarar varias, separadas por comas. Sólo se incluyen aquellas que no se capturen en el Sólo se incluyen aquellas que no se capturen en el interior del método.interior del método.

Es posible lanzar excepciones comprobadas que Es posible lanzar excepciones comprobadas que sean extensiones del tipo de excepción declarado sean extensiones del tipo de excepción declarado en la cláusula en la cláusula throws, throws, ya que una clase se ya que una clase se puede usar polimórficamente allí donde se espera a puede usar polimórficamente allí donde se espera a su superclase.su superclase.

Sólo se puede lanzar un tipo de excepción Sólo se puede lanzar un tipo de excepción comprobada que haya sido declarado en la comprobada que haya sido declarado en la cláusula cláusula throws. throws.

Si un método no tiene cláusula Si un método no tiene cláusula throwsthrows, no , no significa que se pueda lanzar cualquier significa que se pueda lanzar cualquier excepción, sino que no se pueden lanzar excepción, sino que no se pueden lanzar excepciones comprobadas.excepciones comprobadas.

RuntimeExceptionRuntimeException y y ErrorError son las únicas son las únicas excepciones que no hace falta incluir en excepciones que no hace falta incluir en nuestras cláusulas nuestras cláusulas throwsthrows. So ubicuas, y . So ubicuas, y cualquier método puede lanzarlas.cualquier método puede lanzarlas.

Los constructores pueden declarar y lanzar Los constructores pueden declarar y lanzar excepciones comprobadas.excepciones comprobadas.

3 posibilidades3 posibilidadesSi se invoca a un método que tiene una excepción Si se invoca a un método que tiene una excepción comprobada en su cláusula throws, existen tres comprobada en su cláusula throws, existen tres opciones:opciones:

Capturar la excepción y gestionarla.Capturar la excepción y gestionarla.

Capturar la excepción y transformarla en una Capturar la excepción y transformarla en una de nuestras excepciones lanzando una de nuestras excepciones lanzando una excepción de un tipo declarado en nuestra excepción de un tipo declarado en nuestra propia cláusula throws.propia cláusula throws.

Declarar la excepción en nuestra cláusula Declarar la excepción en nuestra cláusula throws y hacer que la excepción pase por throws y hacer que la excepción pase por nuestro método.nuestro método.

Debemos ser explícitos en nuestras cláusulas Debemos ser explícitos en nuestras cláusulas throwsthrows, indicando todas las excepciones , indicando todas las excepciones que sepamos que se pueden lanzar.que sepamos que se pueden lanzar.

Puede ser razonable definir una excepción Puede ser razonable definir una excepción general que se utilice en la cláusula general que se utilice en la cláusula throwsthrows de una interfaz, esperando que las clases de de una interfaz, esperando que las clases de implementación sean más específicas implementación sean más específicas cuando sea posible.cuando sea posible.

Cláusula Cláusula throwsthrows y redefinición de y redefinición de métodosmétodos

No se permite que los métodos de redefinición No se permite que los métodos de redefinición o de implementación declaren más excepciones o de implementación declaren más excepciones comprobadas en la cláusula comprobadas en la cláusula throwsthrows que las que las que declara el método heredado.que declara el método heredado.Se pueden lanzar subtipos de las excepciones Se pueden lanzar subtipos de las excepciones

declaradas ya que podrán ser capturadas en el declaradas ya que podrán ser capturadas en el bloque bloque catchcatch correspondiente a su supertipo. correspondiente a su supertipo.Si una declaración de un método se hereda en Si una declaración de un método se hereda en

forma múltiple, la cláusula forma múltiple, la cláusula throwsthrows de ese de ese método debe satisfacer todas las cláusulas método debe satisfacer todas las cláusulas throwsthrows heredadas. heredadas.

try, catch y finallytry, catch y finally

Las excepciones se capturan encerrando código en Las excepciones se capturan encerrando código en bloques bloques try.try.

try{

sentencias;}catch(excepcion_tipo_1 id1){sentencias}catch(excepcion_tipo_2 id2){sentencias}finally{ sentencias }

El cuerpo de la sentencias El cuerpo de la sentencias trytry se ejecuta se ejecuta hasta que se lance una excepción o hasta hasta que se lance una excepción o hasta que finalice con éxito. Si se lanza una que finalice con éxito. Si se lanza una excepción, se examinan sucesivamente las excepción, se examinan sucesivamente las cláusulas cláusulas catchcatch. Si se encuentra una . Si se encuentra una clausula clausula catchcatch asignable, se ejecuta su asignable, se ejecuta su cuerpo. No se ejecutará ninguna otra cláusula cuerpo. No se ejecutará ninguna otra cláusula catch.catch.

Gestiona una de las excepciones que lanza Gestiona una de las excepciones que lanza sustituirValorsustituirValor

Object valor = new Integer(8);

try

{

objAtribuido.sustituirValor(“Edad”, valor);

}

catch(NoTalAtributoException e)

{

Atrib atrib = new Atrib(e.nombreAtrib, valor);

objAtribuido.añadir(atrib);

}

finallyfinally

La cláusula La cláusula finallyfinally de una sentencia de una sentencia proporciona un mecanismo para ejecutar una proporciona un mecanismo para ejecutar una sección de código, se lance o no una sección de código, se lance o no una excepción. Generalmente, la cláusula excepción. Generalmente, la cláusula finallyfinally se utiliza para limpiar el estado se utiliza para limpiar el estado interno o para liberar recursos que no son de interno o para liberar recursos que no son de objetos, como archivos abiertos almacenados objetos, como archivos abiertos almacenados en variables globales.en variables globales.

public boolean busquedaDe(String archivo, String palabra) throws StreamException

{ Stream entrada = null; try { entrada = new Stream(archivo); while (!entrada.eof()) { if (entrada.next().equals(palabra)) { return true; } } return false; } finally { if (entrada != null) entrada.close(); }}

Este método declara que lanza una excepción StreamException, de forma que cualquier excepción generada se pasa al código que lo invoca tras la operación de limpieza.

Dos formas de usar Dos formas de usar finallyfinally correctamente correctamente

La situación general es que tenemos dos La situación general es que tenemos dos acciones, por ejemplo acciones, por ejemplo prepre y y postpost, de , de forma que si ocurre forma que si ocurre prepre, debe ocurrir , debe ocurrir postpost, independientemente de las , independientemente de las acciones que ocurran entre acciones que ocurran entre prepre y y postpost..

pre();

try

{

//otras acciones

}

finally

{

post();

}

Si pre tiene éxito entraremos en el bloque try e independientemente de lo que ocurra tenemos garantizado que post se ejecutará.

Por otra parte, si pre falla por alguna razón y lanza una excepción, entonces post no se ejecutará (Si está try)

Es importante que pre aparezca fuera del bloque try.

Object val = null;Object val = null;trytry{{ val = pre();val = pre(); //otras acciones //otras acciones

}}finallyfinally{{ if(val != null)if(val != null) post();post();}}

La segunda forma:

pre devuelve un valor que se puede utilizar para determinar si se completó con éxito o no. Sólo si pre se completó con éxito se invoca a post en la cláusula finally

Una cláusula Una cláusula finallyfinally se puede utilizar se puede utilizar también para realizar las acciones finales también para realizar las acciones finales tras sentencias tras sentencias break, continuebreak, continue y y returnreturn. No hay forma de salir de un . No hay forma de salir de un bloque bloque trytry sin ejecutar su cláusula sin ejecutar su cláusula finally.finally.

Qué pasa si Qué pasa si finally finally tiene su propio tiene su propio returnreturn? Se respeta este último, ? Se respeta este último, ingnorando la sentencia ingnorando la sentencia returnreturn del del bloque bloque trytry, independientemente si , independientemente si dentro de dentro de trytry se lanzó alguna se lanzó alguna excepción.excepción.