Sie sind auf Seite 1von 26

EXCEPCIONES

Las excepciones proporcionan una forma


clara de comprobar posibles errores sin
oscurecer el cdigo.
Las excepciones convierten las condiciones
de error que un mtodo puede sealar en una
parte explcita del contrato del mtodo. La
lista de excepciones pueden ser vistas por el
programador, comprobada por el compilador
y preservada (si es necesario) por las clases
extendidas que redefinan el mtodo.

Creacin de tipos de
excepcin
Las excepciones son objetos.
Todos los tipos de excepcin (las clases)
deben extender de la clase Throwable o de
una de sus subclases.
Por convenio, los nuevos tipos de excepcin
extienden a Exception, una subclase de
Throwable

Excepciones
comprobadas
El compilador comprueba que nuestros
mtodos lanzan slo las excepciones que
ellos mismos han declarado que pueden
lanzar.
Representan condiciones que, aunque
excepcionales, se puede esperar
razonablemente que ocurran, y si ocurren
deben ser consideradas de alguna forma.

Excepciones no
comprobadas
Las excepciones no comprobadas
representan condiciones que reflejan errores
en la lgica de nuestro programa de los que
no es posible recuperarse de forma razonable
en ejecucin.

Extendiendo Exception
Algunas veces es til tener ms datos para
describir la condicin excepcional, adems de
la cadena de texto que proporciona
Exception. En estos casos se puede
extender a Exception creando una clase
que contenga los datos aadidos.

Ejemplo
Supongamos que se aade un mtodo
sustituirValor a la interfaz Atribuido
(Cap.4). Este mtodo sustituye el valor actual
de un atributo con nombre por un nuevo
valor. Si dicho atributo con nombre no existe,
se debera lanzar una excepcin.
Esa excepcin debera contener el nombre
del atributo. Se crea la clase
NoTalAtributoException:

public class NoTalAtributoException extends Exception


{
public String nombreAtrib;
public NoTalAtributoException(String nombre)
{
super(El atributo con el nombre \ + nombre +
\ no se encuentra);
nombreAtrib = nombre;
}
}
Toma el nombre del atributo
Almacena el dato en un campo pblico
Invoca al constructor de la superclase con una descripcin en forma de cadena de
texto de lo que ha sucedido.
Almacena una descripcin de la causa del error comprensible para las personas y
los datos que crearon el error

Las excepciones se capturan de acuerdo con


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

Lanzamiento de
excepciones
Las excepciones se lanzan utilizando la
sentencia throw.
throw expresin
Donde expresin es una referencia a un
objeto Throwable.
Se amplia el mtodo sustituirValor de
la clase ImplAtribuido

public void sustituirValor(String nombre, Object nuevoValor)


throws NoTalAtributoException

{
Atrib atrib = buscar(nombre); //busca el atributo
if(atrib == null)
throw new NoTalAtributoException(nombre);
atrib.setValor(nuevoValor);
}
Si se lanza la excepcin no se regresa al flujo normal de
programa.
Las excepciones son objetos, por lo tanto deben crearse
antes de lanzarse.

Transferencia de control
Una vez que se produce una excepcin, las
acciones que hubiera detrs del punto donde
la excepcin se produjo no tiene lugar. La
siguiente accin que ocurrir estar o en un
bloque finally o en un bloque catch que
capture la excepcin

La clusula throws
Declara las excepciones comprobadas que puede
lanzar un mtodo.
Son tan importante como el tipo de valor que
devuelve.
Se pueden declarar varias, separadas por comas.
Slo se incluyen aquellas que no se capturen en el
interior del mtodo.
Es posible lanzar excepciones comprobadas que
sean extensiones del tipo de excepcin declarado
en la clusula throws, ya que una clase se
puede usar polimrficamente all donde se espera a
su superclase.

Slo se puede lanzar un tipo de excepcin


comprobada que haya sido declarado en la
clusula throws.
Si un mtodo no tiene clusula throws, no
significa que se pueda lanzar cualquier
excepcin, sino que no se pueden lanzar
excepciones comprobadas.
RuntimeException y Error son las nicas
excepciones que no hace falta incluir en
nuestras clusulas throws. So ubicuas, y
cualquier mtodo puede lanzarlas.
Los constructores pueden declarar y lanzar
excepciones comprobadas.

3 posibilidades
Siseinvocaaunmtodoquetieneunaexcepcin
comprobadaensuclusulathrows,existentresopciones:

Capturar la excepcin y gestionarla.


Capturar la excepcin y transformarla en una
de nuestras excepciones lanzando una
excepcin de un tipo declarado en nuestra
propia clusula throws.
Declarar la excepcin en nuestra clusula
throws y hacer que la excepcin pase por
nuestro mtodo.

Debemos ser explcitos en nuestras clusulas


throws, indicando todas las excepciones
que sepamos que se pueden lanzar.
Puede ser razonable definir una excepcin
general que se utilice en la clusula throws
de una interfaz, esperando que las clases de
implementacin sean ms especficas
cuando sea posible.

Clusula throws y redefinicin de


mtodos
No se permite que los mtodos de redefinicin
o de implementacin declaren ms excepciones
comprobadas en la clusula throws que las
que declara el mtodo heredado.
Se pueden lanzar subtipos de las excepciones
declaradas ya que podrn ser capturadas en el
bloque catch correspondiente a su supertipo.
Si una declaracin de un mtodo se hereda en
forma mltiple, la clusula throws de ese
mtodo debe satisfacer todas las clusulas
throws heredadas.

try, catch y finally


Las excepciones se capturan encerrando cdigo en
bloques try.
try
{
sentencias;
}
catch(excepcion_tipo_1id1)
{sentencias}
catch(excepcion_tipo_2id2)
{sentencias}
finally
{sentencias}

El cuerpo de la sentencias try se ejecuta


hasta que se lance una excepcin o hasta
que finalice con xito. Si se lanza una
excepcin, se examinan sucesivamente las
clusulas catch. Si se encuentra una
clausula catch asignable, se ejecuta su
cuerpo. No se ejecutar ninguna otra clusula
catch.

Gestiona una de las excepciones que lanza


sustituirValor
Object valor = new Integer(8);
try
{
objAtribuido.sustituirValor(Edad, valor);
}
catch(NoTalAtributoException e)
{
Atrib atrib = new Atrib(e.nombreAtrib, valor);

objAtribuido.aadir(atrib);
}

finally
La clusula finally de una sentencia
proporciona un mecanismo para ejecutar una
seccin de cdigo, se lance o no una
excepcin. Generalmente, la clusula
finally se utiliza para limpiar el estado
interno o para liberar recursos que no son de
objetos, como archivos abiertos almacenados
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))
Este mtodo declara que
{
return true;
lanza una excepcin
}
StreamException, de forma
}
que cualquier excepcin
return false;
generada se pasa al cdigo
}
que lo invoca tras la
finally
{
operacin de limpieza.
if (entrada != null)
entrada.close();
}
}

Dos formas de usar finally correctamente


La situacin general es que tenemos dos
acciones, por ejemplo pre y post, de
forma que si ocurre pre, debe ocurrir
post, independientemente de las
acciones que ocurran entre pre y post.

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 razn y lanza una
excepcin, entonces post no se
ejecutar (Si est try)
Es importante que pre aparezca
fuera del bloque try.

Object val = null;


try
{
val = pre();
//otras acciones
}
finally
{
if(val != null)
post();
}

La segunda forma:
pre devuelve un valor que
se puede utilizar para
determinar si se complet
con xito o no. Slo si pre
se complet con xito se
invoca a post en la clusula
finally

Una clusula finally se puede utilizar


tambin para realizar las acciones finales
tras sentencias break, continue y
return. No hay forma de salir de un
bloque try sin ejecutar su clusula
finally.
Qu pasa si finally tiene su propio
return? Se respeta este ltimo,
ingnorando la sentencia return del
bloque try, independientemente si
dentro de try se lanz alguna
excepcin.