Gestión de Excepciones

21
Gestión de Excepciones Excepciones. Categorías. Las excepciones son el mecanismo por el cual pueden controlarse en un programa Java las condiciones de error que se producen. Estas condiciones de error pueden ser errores en la lógica del programa como un índice de un array fuera de su rango, una división por cero o errores disparados por los propios objetos que denuncian algún tipo de estado no previsto, o condición que no pueden manejar. La idea general es que cuando un objeto encuentra una condición que no sabe manejar crea y dispara una excepción que deberá ser capturada por el que le llamó o por alguien más arriba en la pila de llamadas. Las excepciones son objetos que contienen información del error que se ha producido y que heredan de la clase Throwable o de la clase Exception. Si nadie captura la excepción interviene un manejador por defecto que normalmente imprime información que ayuda a encontrar quién produjo la excepción. Existen dos categorías de excepciones: Excepciones verificadas: El compilador obliga a verificarlas. Son todas las que son lanzadas explicitamente por objetos de usuario. Excepciones no verificadas: El compilador no obliga a su verificación. Son excepciones como divisiones por cero, excepciones de puntero nulo, o índices fuera de rango.

description

doc

Transcript of Gestión de Excepciones

Gestin de ExcepcionesExcepciones. Categoras.Las excepciones son el mecanismo por el cual pueden controlarse en un programa Java las condiciones de error que se producen. Estas condiciones de error pueden ser errores en la lgica del programa como un ndice de un array fuera de su rango, una divisin por cero o errores disparados por los propios objetos que denuncian algn tipo de estado no previsto, o condicin que no pueden manejar. La idea general es que cuando un objeto encuentra una condicin que no sabe manejar crea y dispara una excepcin que deber ser capturada por el que le llam o por alguien ms arriba en la pila de llamadas. Las excepciones son objetos que contienen informacin del error que se !a producido y que !eredan de la clase "!ro#able o de la clase Exception. $i nadie captura la excepcin interviene un manejador por defecto que normalmente imprime informacin que ayuda a encontrar qui%n produjo la excepcin. Existen dos categoras de excepciones& Excepciones verificadas& El compilador obliga a verificarlas. $on todas lasque son lan'adas explicitamente por objetos de usuario. Excepciones no verificadas& El compilador no obliga a su verificacin. $on excepciones como divisiones por cero, excepciones de puntero nulo, ondices fuera de rango.Generacin de excepciones$upongamos que tenemos una clase Empresa que tiene un array de objetos Empleado (clase vista en captulos anteriores). En esta clase podramos tener m%todos para contratar un Empleado (a*adir un nuevo objeto al array), despedirlo (quilarlo del array) u obtener el nombre a partir del nmero de empleado. La clase podra ser algo as como lo siguiente&public class Empresa {String nombre;Empleado [] listaEmpleados;int totalEmpleados = 0;. . .Empresa(String n, int maxEmp) {nombre = n;listaEmpleados = new Empleado [maxEmp];}. . .void nuevoEmpleado(String nombre, int sueldo) { if (totalEmpleados < listaEmpleados.length ) {listaEmpleados[totalEmpleados++] = new Empleado(nombre,sueldo); }}}+bservese en el m%todo nuevoEmpleado que se comprueba que !ay sitio en el array para almacenar la referencia al nuevo empleado. $i lo !ay se crea el objeto. ,ero si no lo !ay el m%todo no !ace nada ms. -o da ninguna indicacin de si la operacin !a tenido %xito o no. $e podra !acer una modificacin para que, por ejemplo el m%todo devolviera un valor booleano true si la operacin se !a completado con %xito y false si !a !abido algn problema. +tra posibilidad es generar una excepcin verificada (.na excepcin no verificada se producira si no se comprobara si el nuevo empleado va a caber o noen el array). /amos a ver como se !ara esto.Las excepciones son clases, que !eredan de la clase gen%rica Exception. Es necesario por tanto asignar un nombre a nuestra excepcin. $e suelen asignar nombres que den alguna idea del tipo de error que controlan. En nuestro ejemplo le vamos a llamar 0apacidadEmpresaExcedida. ,ara que un m%todo lance una excepcin& 1ebe declarar el tipo de excepcin que lan'a con la clusula t!ro#s, en su declaracin. 1ebe lan'ar la excepcin, en el punto del cdigo adecuado con la sentencia t!ro#.En nuestro ejemplo&void nuevoEmpleado(String nombre, int sueldo) throws CapacidadEmpresaExcedida { if (totalEmpleados < listaEmpleados.length) {listaEmpleados[totalEmpleados++] = new Empleado(nombre,sueldo); } else throw new CapacidadEmpresaExcedida(nombre);}2dems, necesitamos escribir la clase CapacidadEmpresaExcedida. $era algo as&public class CapacidadEmpresaExcedida extends Exception { CapacidadEmpresaExcedida(String nombre) {super("No es posible aadir el empleado " + nombre);}. . .}La sentencia t!ro# crea un objeto de la clase CapacidadEmpresaExcedida . El constructor tiene un argumento (elnombre del empleado). El constructor simplemente llama al constructor de la superclase pasndole como argumento un texto explicativo del error ( y el nombre del empleado que no se !a podido a*adir).La clase de la excepcin puede declarar otros m%todos o guardar datos de depuracin que se consideren oportunos. El nico requisito es que extienda la clase Exception. 0onsultar la documentacin del 2,3 para ver una descripcin completa de la clase Exception. 1e esta forma se pueden construir m%todos que generen excepciones.Captura de excepciones0on la primera versin del m%todo nuevoEmpleado (sin excepcin) se invocara este m%todo de la siguiente forma&Empresa em = new Empresa("La Mundial");em.nuevoEmpleado("Adn Primero",500);$i se utili'ara este formato en el segundo caso (con excepcin) el compilador producira un error indicando que no se !a capturado la excepcin verificada lan'ada por el m%todo nuevoEmpleado. ,ara capturar la excepcin es utili'a la construccin try 4 catc!, de la siguiente forma&Empresa em = new Empresa("La Mundial");try {em.nuevoEmpleado("Adn Primero",500);} catch (CapacidadEmpresaExcedida exc) {System.out.println(exc.toString());System.exit(1);} $e encierra el cdigo que puede lan'ar la excepcin en un bloque try 4 catc!. 2 continuacin del catc! se indica que tipo de excepcin se va a capturar. 1espu%s del catc! se escribe el cdigo que se ejecutar si se lan'a la excepcin. $i no se lan'a la excepcin el bloque catc! no se ejecuta.El formato general del bloque try 4 catc! es&try { . . .} catch (Clase_Excepcion nombre) { . . .}catch (Clase_Excepcion nombre) { . . .} . . . +bservese que se puede capturar ms de un tipo de excepcin declarando ms de una sentencia catc!. "ambi%n se puede capturar una excepcin gen%rica (clase Exception) que engloba a todas las dems.En ocasiones el cdigo que llama a un m%todo que dispara una excepcin tampoco puede (o sabe) manejar esa excepcin. $i no sabe que !acer con ella puede de nuevo lan'arla !acia arriba en la pila de llamada para que la gestione quien le llamo (que a su ve' puede capturarla o reenviarla). 0uando un m%todo no tiene intencin de capturar la excepcin debe declararla metdiante la clusula t!ro#s, tal como !emos visto en el m%todo que genera la excepcin. $upongamos que, en nuestro ejemplo es el m%todo main de una clase el que invoca el m%todo nuevoEmpleado. $i no quiere capturar la excepcin debe !acer lo siguiente&public static void main(String [] args) throws CapacidadEmpresaExcedida {Empresa em = new Empresa("La Mundial");em.nuevoEmpleado("Adn Primero",500);}Clusula finallyLa clusula finally forma parte del bloque try 4 catch y sirve para especificar un bloque de cdigo que se ejecutar tanto si se lan'a la excepcin como si no. ,uede servir para limpie'a del estado interno de los objetos afectadoso para liberar recursos externos (descriptores de 5306E7+ , por ejemplo). La sintaxis global del bloque try 4 catch 4 finally es&try { . . .} catch (Clase_Excepcion nombre) { . . .}catch (Clase_Excepcion nombre) { . . .} . . . finally { . . .}http://www.cc.uah.es/jlcastillo/POO/media/JavaCap4.pdfhttp://www.mundojava.net/excepciones.html?Pg=java_inicial_4_.htmlhttp://codehe!o.co/manejo"de"excepciones"pa!te/http://www.cu!sohi#e!nate.es/do$u.php?id=pat!ones:excepcionesExcepciones en JavaEmpecemos recordando los dos tipos de excepciones que hay en Java1) Excepciones Checked: Objetos de la clase Exception o cualquier otra clase que heredade ella, excepto si heredan de RuntimeException Excepciones!nchecked: Objetosdelaclase RuntimeException odecualquieraotraclase que herede de ellaExcepciones Checked"as excepciones Checked son aquellas que deben declararse en el m#todo mediante lapalabra throws y que obli$an al que lo llama a hacer un tratamiento de dicha excepci%n&on excepciones Checked cualquier objeto de la clase Exception o de cualquier otra clase queherede de ella, excepto si el objeto es de la clase RuntimeException o cualquier otra clase queherede de #sta 'ltima 1: public class Matematicas { 2: public double dividir(double a, double b) throws Exception { 3: if (b == 0) { 4: throw new Exception("El argumento b no puede ser 0"); 5: } 6: 7: return a / b; 8: } 9: }El m#todo dividir lan(a en la l)nea * una Checked Exception por lo tanto el m#todo lo declaramediante throws+hora cualquiera que llame al m#todo dividir est, obli$ado a tratar la excepci%n Exception dedos -ormas: .ediante un trycath:1: public class Main {2: public static void main(String[] args) {3: Matematicas matematicas=new Matematicas();4: try {5: double c=matematicas!dividir("!#, 0);6: } catch (Exception ex) {7: //Tratar la excepcin8: }9: } 10: }Enlasl)neas*,/,0y1, seusaun trycatch para atrapar laexcepci%nquepuedeproducir la llamada el m#todo dividir 2eclar,ndo a su ve( en el m#todo que puede lan(ar dicha excepci%n: 1: public class Main { 2: public static void main(String[] args) throws Exception { 3: Matematicas matematicas=new Matematicas(); 4: 5: double c=matematicas!dividir("!#, 0); 6: } 7: }En la l)nea 3 vemos como se declara4que el m#todo main puede lan(ar una excepci%ndel tipo Exception ya que dividir lo lan(a y no se atrapa con un trycatchExcepciones Unchecked"as excepciones !nchecked son aquellas que no se declaran en elm#todo y que no obli$an alque lo llama a hacer un tratamiento de dicha excepci%n&on excepciones !nchecked todas aquellas excepciones que heredan de laclase RuntimeException 1: public class Matematicas { 2: public double dividir(double a, double b) { 3: if (b == 0) { 4: throw new RuntimeException("El argumento b no puede ser0"); 5: } 6: 7: return a / b; 8: } 9: }El m#todo dividir lan(a en la l)nea * una unchecked Exception por lo que no es necesario hacernada especial con ella1: public class Main {2: public static void main(String[] args) {3: Matematicas matematicas=new Matematicas();4:5: double c=matematicas!dividir("!#, 0);6: }7: }Como la excepci%n que lan(a dividir es !nchecked no necesitamos tratarla en elm#todo main de nin$una -orma especialCuando usar excepciones Checked o !nchecked y que hacer conellas!nave(vistocomoJavatratalasexcepcionesdeambostipospasemosaexplicar cuandodebemos usar las de un tipo u otroChecked Exceptions"as excepciones Checked son condiciones excepcionales del -lujo del pro$rama pero que no sondebido a un error del propio pro$rama Es decir si se lan(a una excepci%n checked el pro$rama notiene nin$'n tipo de error y si$ue -uncionando correctamente, simplemente se ha producido unasituaci%n excepcional que hemos marcado como una excepci%n5or ejemplo si tenemos una -unci%n que borra -icheros y al ir a borrarlo , dicho 67C8E9Oya noexiste, deberemos lan(ar una $ile%ot$oundException indicando que el -ichero no existe :ueel -ichero ya no exista no es nin$'n error en el pro$rama, puede haberse borrado justo un instanteantes , sin embar$o, si que es una situaci%n excepcional porque la mayor)a de las veces cuandovayamos a borrarlo deber, estar el -ichero si hemos acabado de seleccionarlo2e ah) que al ser usa situaci%n le$itima del pro$rama pero poco probable los creadores de Javahan decidido que es necesario declararla en el m#todo y que sea obli$atorio tratarla "as CheckedExceptions no tienen nada de malo y son muy 'tiles para reali(ar correctamente los pro$ramas"a Checked Exceptions -orman parte del -lujo l%$ico de nuestro pro$rama y al pro$ramar debemostenerlas en cuenta y tratarlas adecuadamente no vi#ndolas como un problema del que debemosdeshacernos+unque hemos puesto el mismo ejemplo del m#todo dividir tanto para explicar las excepcionesChecked o !ncheked tras la explicaci%n debe quedar claro que la excepci%n que debe lan(ar elm#todo dividir debe ser del tipo uncheckedUnchecked ExceptionsEste tipo de error es mucho mas sencillo de entender !na excepci%n unchecked es aquella que selan(a cuando hay un error en el pro$rama5or ejemplo en el caso anterior de la divisi%n por cero, es un error de pro$ramaci%n que al$uiennos pase como dividendo un cero, en ese caso lan(aremos un RuntimeException+l ser las unchecked Exceptions errores en el pro$rama , poco podemos hacer por arre$larlas 5orello no es obli$atorio tratarlas con un trycatch "o 'nico que podemos hacer en la mayor)a decasos es hacer que el pro$rama acabe -allando y que se muestre un mensaje de error al usuarioEs decir, sielpro$rama -unciona mal, es mejor que no si$a -uncionando antes que hacer quecontin'e -uncionado pero usando datos err%neos, ya que en ese caso los resultados que $eneraratambi#n podr)an ser err%neos"as unchecked exceptions no debemos tratarlas ya que no -orma parte de la l%$ica de la aplicaci%nynodebemoshacer nadaconella, simplementedebemospreocuparnosenel mensajequeacabar, lle$ando al usuario En una aplicaci%n ;eb es tan sencillo como tener p,$inas de errorpersonali(adasEl problema con las excepciones8asta ahora hemos visto los dos tipos de excepciones que hay , como las trata el compilador deJava y cuando usar una u otra &in embar$o hay un problema con las excepciones que hace queno se traten de -orma correctaEl problemadelasexcepcionesesqueenmuchas +57sdeJavaselan(ancheckedcuandodeber)an ser unchecked5or ejemplo, en el +57 de J25uessolohayuna-ormadehacerlo, estrans-ormando las excepciones Checked en unchecked1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (Exception ex) {4: throw new RuntimeException("$allo al llamar a -dividir-",ex)5: }?emos en la l)nea * como lan(amos una nueva excepci%n del tipo unchecked pero dentro contienela excepci%n ori$inalque se ha producido ya que se le pasa como ar$umento Con #sto hemossolucionado el problema 5ero vuelvo a repetir #sta construcci%n solo debe hacerse con aquellasexcepciones checked que consideramos que deber)an haber sido uncheckedEsta construcci%n tan sencilla que consiste en que las excepciones checked ,pero que deberanhaber sido uncheked, tras-ormarlas en excepciones uncheked nos soluciona pr,cticamente todosnuestros problemas1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (Exception ex) {4: throw new RuntimeException("$allo al llamar a -dividir-",ex)5: }Mas problemas?eamosahoraotroproblemadelasexcepciones8ayexcepcionesunchecked, quese$'nsusi$ni-icado, deber)an haber sido del tipo checked ya que no son debido a errores del pro$rama @locontrario del caso anterior)"aexcepci%n .onstraint/iolationException se lan(a cuandoal$unavalidaci%n deunaentidad no se ha cumplido &e suele utili(ar para indicar que el usuario ha introducido al$'n datoerroneo en la aplicaci%n Entonces, =porqu# es una excepci%n unchecked> &e$'n lo que se est,explicando no hay duda de que deber)a ser del tipo Checked ya que no se lan(a por un error depro$ramaci%n sino a causa de un dato mal introducido por el usuarioEl problema que se $enera con #sto es que la excepci%n .onstraint/iolationException nosabemos que m#todo la va a lan(ar a no ser que nos leamos la documentaci%n, pero es importantecapturarla para poder mostrar un mensaje al usuario &i hubiera sido declarada como Checked, elpropio compilador nos avisar)a de cuando capturarla Aodo #sto nos puede llevar a que el usuarioacabe viendo nuestra p,$ina de error de la aplicaci%n simplemente porque se ha dejado un camposin rellenarOtro problema de Java es que hay +57s que lan(an !nChecked Exceptions cuando deber)an habersido Cheked Exceptions"a soluci%n a este problema consiste simplemente en leerse la documentaci%n para ver cuando selan(aunaexcepci%nunchecked, quedeber)ahabersidoChecked, paracapturarlayhacerelcorrecto tratamiento con ella.asin-ormaci%nsobrelaexcepci%n .onstraint/iolationException ycomosolucionar elproblema lo tenemos en Excepciones6ormas err%neas de tratar las excepciones?eamos ahora una serie de errores que se cometen al tratar las excepcionesPerder la excepcin original:ui(,s otro ori$en deldesconocimiento de las excepciones es que hasta Java 1* no se pod)aencapsular unaexcepci%ndentrodeotra "opodemosver enlaclase 0hrowable delaquehereda Exception AhroBableenJava1C: Doexistenunconstructor queaceptecomoar$umentootraexcepci%n ni el m#todo 0hrowable get.ause'( que obtiene la excepci%nencapsulada AhroBable en Java 1*: Ea dispone de un constructor al que pasarle otra excepci%n y elm#todo 0hrowable get.ause'(Esto 'ltimo nos ha llevado a soluciones err%neas como la si$uiente:1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (Exception ex) {4: thrownewRuntimeException("$all1 al llamar a -dividir-2"3ex!getMessage());5: }En la l)nea * vemos como se crea una RuntimeException pero de la excepci%n ori$inal se hapedidolatra(acompletaysolovamosaconse$uirel mensajedeerror,perolasexcepcionespueden tener mucha mas in-ormaci%n que simplemente el mensaje y la tra(a5or ejemplo la excepci%n +&,Exception dispone de losm#todos get+&,+tate'( y getError.ode'( que contiene in-ormaci%n sobre el error concretoque ha ocurrido en la base de datos !sando el c%di$o anterior tambi#n lo habr)amos perdidoCrear una excepcin inutilOtro se$undo error es crear una nueva excepci%n generica 3) que no aporta nada respectoa RuntimeException C) y usarla en ve( de RuntimeException1: public class MiExcepcion extends RuntimeException {2: public MiExcepcion (String msg) {3: super(msg);4: }5: }Creando una excepci%n personali(ada que no aporta nada1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (Exception ex) {4: throw new MiExcepcion ("$all1 al llamar a -dividir-!");5: }Enlal)nea*selan(alanuevaexcepci%n MiExcepcion quenohacenadaquenohicieraya RuntimeException e incluso se$uimos perdiendo la excepci%n ori$inalPasar el problema hacia arriba"a si$uiente -orma err%nea de tratar la excepciones es simplemente hacer que el m#todo superiora su ve( declare que lan(a esas excepciones checked pero que deber)an haber sido unchekedCon #sto lo 'nico que hacemos es expandir el problema hacia arriba sin solucionarlo1: public class Main {2: public static void main(String[] args) throws Exception {3: Matematicas matematicas=new Matematicas();4:5: double c=matematicas!dividir("!#, 0);6: }7: }En la l)nea 3 vemos ahora como el m#todo Main ahora tambi#n lan(a una excepci%n checkedIgnorarlaEsteesel peor error quepodemoscometer al tratar unaexcepci%nConsistesimplementeeni$norar la excepci%n y que contin'e la ejecuci%n del pro$rama Esto es tan peli$roso ya que si seha producido al$'n -allo en el pro$rama lo m,s se$uro es hacer que se deten$a cuanto antes y nose$uir haciendo operaciones con datos que qui(,s sean err%neos1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (Exception ex) {4:5: }?emos en la l)nea * como no se reali(a nin$una acci%n al capturar la excepci%n, por lo tanto laejecuci%n se$uir, como si no hubiera pasado nadaLog+cabamos de ver en el apartado anterior que nunca *) se debe i$norar la excepci%n !na -orma dei$norarlaperoqueaparentaser mejor soluci%nes$uardar enel lo$laexcepci%nquesehaproducido pero sin hacer nada mas1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (RuntimeException ex) {4:,ogger!get,ogger(Main!class!get%ame())!log(,evel!+E/ERE,null,ex);5: }En la l)nea * $uardamos en el lo$ la excepci%n pero el pro$rama si$ue ejecut,ndose Como yahemos comentado no deber)a se$uir la ejecuci%n del pro$rama puesto que los datos pueden haberquedado en un estado err%neo"aideade$uardarenel lo$laexcepci%nesbuenaporsi misma &inembar$onosuelesernecesario $uardarla expl)citamente ya que en muchas ocasiones ya se $uarda autom,ticamente5or ejemplo en aplicaciones ;eb , el propio contenedor al detectar F) una excepci%n $uardar, en ello$ la excepci%n que se ha producidoConsolaOtra-ormaerroneade$uardar lasexcepcionesconsisteenmostrar latra(adel error por laconsola1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (RuntimeException ex) {4: ex!print+tac40race();5: }En la l)nea * mostramos por la consola la tra(a dela excepci%n pero el pro$rama si$ueejecut,ndose Como ya se ha dicho no deber)a se$uir la ejecuci%n del pro$rama puesto que losdatos pueden haber quedado en un estado err%neoEn aplicaciones ;eb o aplicaciones de ?entanas , esta opci%n tiene menos sentido aun que laopci%n dello$, ya que $uardando la tra(a en un -ichero de lo$ est, mucho m,s accesible parapoder averi$uar el ori$en del problema que mostr,ndolo por consola ya que la consola la puedecerrar el usuario y perder toda la tra(a o simplemente que no ten$amos acceso a la consolaImprimirla5or 'ltimo pero no por ello menos usada est, la tcnica de imprimir el mensaje de la excepci%n1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (RuntimeException ex) {4: System!out!println("$all1 al dividir");5: }Esta -orma tiene los mismos problemas delanterior de imprimirla por consola pero #sta es aunpeor, hemos perdido toda la in-ormaci%n de la excepci%n.ejoras en el tratamiento de excepcionesEahemosvistocomoesla-ormacorrectadetratar lasexcepcionesCheckedquerealmentedeber)an ser unchecked:1: try {2: double c=matematicas!dividir("!#, 0);3: } catch (Exception ex) {4: throw new RuntimeException("$allo al llamar a -dividir-",ex)5: }Este c%di$o tiene unas pe$as al respecto de las tra(as que se $enerara por pantalla /) cuando seproduce una excepci%n&i ejecutamos el c%di$o se produce la si$uiente tra(a:1: Exception in thread "main" )ava!lang!RuntimeException2 $allo al llamara -dividir-2: at e)emplo!Main!main'Main!)ava2"5(3: .aused by2 )ava!lang!Exception2 El argumento b no puede ser 04: at e)emplo!Matematicas!dividir'Matematicas!)ava2"6(5: at e)emplo!Main!main'Main!)ava2"7(Como podemos ver en la tra(a, se muestran dos excepciones, la excepci%n ori$inal en la l)nea C yla RuntimeExcepcion que encapsula a la excepci%n ori$inal en la l)nea 1 Esto es inevitable as)que por ahora lo vamos a asumirEl problema viene si el m#todo dividir puede lan(ar tanto una Exception comouna RuntimeException?eamos el c%di$o modi-icado de dividir para que en caso de que al$'n n'mero sea ne$ativo seprodu(ca una RuntimeException: 1: public class Matematicas { 2: public double dividir(double a, double b) throws Exception { 3: if (a80) { 4: throw new RuntimeException("El argumento a no puede sernegativo"); 5: } 6: if (b80) { 7: throw new RuntimeException("El argumento b no puede sernegativo"); 8: } 9:10: if (b == 0) {11: throw new Exception("El argumento b no puede ser 0");12: }13:14: return a / b;15: }16: }?emos en las l)neas de la C a la 1 como ahora tambi#n se lan(a un RuntimeException&i volvemos ahora a ejecutar el pro$rama se $enera la si$uiente tra(a de error:1: Exception in thread "main" )ava!lang!RuntimeException2 $allo al llamara -dividir-2: at e)emplo!Main!main'Main!)ava2"5(3:.aused by2 )ava!lang!RuntimeException2 El argumento a no puede sernegativo4: at e)emplo!Matematicas!dividir'Matematicas!)ava2"6(5: at e)emplo!Main!main'Main!)ava2"7(+hora la tra(a si que ha quedado un poco mal8emos encapsuladouna RuntimeException @l)nea C) dentro de otra RuntimeException @l)nea 1) lo que tiene muypoco sentido Es decir que la tra(a ha quedado poco clara cuando no hay necesidad para ello Estoocurreyaque RuntimeException heredade Exception por loqueel catch tambi#natrapala RuntimeException y la encapsula en otra RuntimeException"asoluci%na#sto, esbastantesencilla&i noslle$auna RuntimeException simplementelavolvemos a lan(ar en ve( de encapsularla 1: public class Main { 2: public static void main(String[] args) { 3: Matematicas matematicas=new Matematicas(); 4: try { 5: double c=matematicas!dividir("!#, 0); 6: } catch (RuntimeException ex) { 7: throw ex; 8: } catch (Exception ex) {9: thrownewRuntimeException("$allo al llamar a-dividir-",ex);10: }11: }12: }En la l)nea / ahora capturamos la RuntimeException y altratarla simplemente relan(amos lamisma excepci%n @l)nea 0)&i ahora volvemos a ejecutar el c%di$o, la tra(a resultante es:1: Exception in thread "main" )ava!lang!RuntimeException2 El argumento ano puede ser negativo2: at e)emplo!Matematicas!dividir'Matematicas!)ava2"6(3: at e)emplo!Main!main'Main!)ava2"7(Es decir que ahora la tra(a para una RuntimeException es como deber)a ser ,ya que no quedaencapsulada por nin$una otra excepci%n5or los ejemplos puede parecer un poco exa$erado querer que no se encapsulen las excepcionespero pon$o aqu) un ejemplo de excepciones en 8ibernate:Exception in thread "main" org!hibernate!MappingException2 .ould not getconstructor 9or org!hibernate!persister!entity!+ingle0ableEntity:ersisteratorg!hibernate!persister!internal!:ersister$actory;mpl!create':ersister$actory;mpl!)ava2"':o)oEntity0upliBer!)ava2