Programación

1º DAM/DAW - Curso 2023-2024

User Tools

Site Tools


apuntes:excepciones

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
apuntes:excepciones [2021/03/10 13:37] Santiago Faciapuntes:excepciones [2023/06/04 18:31] (current) – [Excepciones] Santiago Faci
Line 8: Line 8:
 que, en Java, acaban lanzando una excepción si llegan a producirse: que, en Java, acaban lanzando una excepción si llegan a producirse:
  
-\begin{itemize} +  * Estamos escribiendo en disco y éste se llena (''IOException''
-    \item Estamos escribiendo en disco y éste se llena (\verb IOException ) +  Estamos descargando un fichero y cae la conexión a Internet (''ConnectionException''
-    \item Estamos descargando un fichero y cae la conexión a Internet (\verb ConnectionException ) +  Estamos recorriendo un array en un bucle y accedemos a una posición que no existe (''IndexOutOfBoundException''
-    \item Estamos recorriendo un array en un bucle y accedemos a una posición que no existe (\verb IndexOutOfBoundException ) +  Accedemos atributos o métodos de un objeto cuyo valor es nulo (''NullPointerException''
-    \item Accedemos atributos o métodos de un objeto cuyo valor es nulo (\verb NullPointerException ) +  Realizamos una operación matemática no válida (división por cero) (''ArithmeticException'')
-    \item Realizamos una operación matemática no válida (división por cero) (\verb ArithmeticException ) +
-    \item . . . +
-\end{itemize}+
  
-En Java se propone el control de excepciones para evitar que se produzcan estos errores en lugar de tener que escribir continuamente +En Java se propone el control de excepciones para evitar que se produzcan estos errores en lugar de tener que escribir continuamente estructuras ''if'' que controlen que no ocurre nada anómalo que impida la ejecución de un cierto código. Así, lo que haremos será colocar dentro un bloque controlado todo el código (y el que dependa de éste) que sea susceptible de producir una excepción, sin interrumpir el flujo de nuestro programa (al contrario de lo que ocurre añadiendo sentencias ''if'').
-estructuras \verb if  que controlen que no ocurre nada anómalo que impida la ejecución de un cierto código. Así, lo que haremos será colocar +
-dentro un bloque controlado todo el código (y el que dependa de éste) que sea susceptible de producir una excepción, sin interrumpir el +
-flujo de nuestro programa (al contrario de lo que ocurre añadiendo sentencias \verb if ).+
  
-Se recomienda excepciones como \verb NullPointerException  \verb IndexOfOutBoundException  no se traten como tal ya que, por lo +Se recomienda excepciones como ''NullPointerException'' ''IndexOfOutBoundException'' no se traten como tal ya que, por lo general, corresponderán a errores de codificación, por lo que realmente, se debería evitar que se produjeran corrigiendo el programa y no esperando capturarlas cuando se produzcan. Son dos excepciones que derivan de ''RuntimeException''. Son lo que se conoce como //unchecked exceptions//. Echa un vistazo a [[https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html|Documentación sobre excepciones]] para más información al respecto.
-general, corresponderán a errores de codificación, por lo que realmente, se debería evitar que se produjeran corrigiendo el programa y no +
-esperando capturarlas cuando se produzcan. Son dos excepciones que derivan de \verb RuntimeException . Son lo que se conoce como +
-\emph{unchecked exceptions}. Echa un vistazo a  +
- \href{https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.htmlpara más información al respecto.+
  
-\subsection{Bloque try-catch}+==== Tipos de Excepciones ====
  
-El bloque \verb try-catch  es el bloque Java que permite delimitar el código susceptible de generar excepción (parte \verb try ) y ejecutar otro bloque +=== Checked Exceptions ===
-para corregir o notificar el problema (parte \verb catch ).+
  
-\begin{lstlisting}[language=java]+  * Excepciones que deben ser capturadas o declaradas en el método donde se producen 
 +  * Heredan directamente de la clase ''Exception'' 
 +  * Por norma general serán el tipo de excepciones que deberemos capturar siempre en nuestro código 
 +  * ''IOException'' y ''ParseException'' son dos ejemplos de excepciones //checked// 
 + 
 +=== Unchecked Exceptions === 
 + 
 +  * Excepciones que pueden ser lanzadas sin ser capturadas o declaradas 
 +  * Heredan de la clase ''RuntimeException'', que a su vez hereda de ''Exception'' 
 +  * Por norma general serán el tipo de excepciones que no deberemos capturar. Deberíamos evitar que se produjeran como, por ejemplo, en el caso de la excepción //unchecked// ''NullPointerException'' 
 +  * ''ArithmeticException'' y ''ArrayIndexOutOfBoundsException'' son otros ejemplos de excepciones "unchecked" 
 + 
 +==== Bloque try-catch ==== 
 + 
 +El bloque //try-catch// es el bloque Java que permite delimitar el código susceptible de generar excepción (parte //try//) y ejecutar otro bloque 
 +para corregir o notificar el problema (parte //catch//). 
 + 
 +<code java>
 . . . . . .
 try { try {
Line 42: Line 48:
  
 . . . . . .
-\end{lstlisting}+</code>
  
-En este caso, el código que hay asociado al bloque \verb try  se ejecutará de forma que, si dentro de él se produjera una excepción, el +En este caso, el código que hay asociado al bloque //try// se ejecutará de forma que, si dentro de él se produjera una excepción, el flujo de ejecución pasaría al bloque //catch// de la excepción que corresponda. A continuación, seguirá ejecutando justo al final de todo 
-flujo de ejecución pasaría al bloque \verb catch  de la excepción que corresponda. A continuación, seguirá ejecutando justo al final de todo +el grupo //try-catch//.
-el grupo \verb try-catch .+
  
-\begin{lstlisting}[language=java]+<code java>
 . . . . . .
 File fichero = null; File fichero = null;
Line 68: Line 73:
 } }
 . . . . . .
-\end{lstlisting}+</code>
  
 ==== Instrucción throws ==== ==== Instrucción throws ====
  
-También podemos, en lugar de capturar la excepción, lanzarla haciendo que tenga que ser controlada en un nivel superior. Por ejemplo, si +También podemos, en lugar de capturar la excepción, lanzarla haciendo que tenga que ser controlada en un nivel superior. Por ejemplo, si estoy desarrollando una clase que debe controlar una determinada excepción, quizás me pueda resultar interesante hacerla "subir" de nivel para que sea controlada, por ejemplo, en el controlador de la aplicación o bien cerca de la interfaz con el usuario. Así es probable que podamos ajustar mejor el comportamiento en caso de error.
-estoy desarrollando una clase que debe controlar una determinada excepción, quizás me pueda resultar interesante hacerla "subir" de nivel +
-para que sea controlada, por ejemplo, en el controlador de la aplicación o bien cerca de la interfaz con el usuario. Así es probable que +
-podamos ajustar mejor el comportamiento en caso de error.+
  
-\begin{lstlisting}[language=java]+<code java>
 public class Util { public class Util {
     public static Date parseFecha(String fecha) throws ParseException {     public static Date parseFecha(String fecha) throws ParseException {
Line 84: Line 86:
     }     }
 } }
-\end{lstlisting}+</code>
  
-El ejemplo de arriba es un caso en el que tenemos un método estático que utilizamos para parsear fechas en nuestra aplicación. Cuando el +El ejemplo de arriba es un caso en el que tenemos un método estático que utilizamos para parsear fechas en nuestra aplicación. Cuando el texto que se le pase no se corresponda con un formato válido de fecha, lanzará una excepción. Pero justamente en el método no tenemos muy claro que hacer puesto que dicho método lo utilizarán desde diferentes localizaciones del código en la aplicación. Por eso es mejor que lancemos fuera la excepción para que sea quién utilice este método quién deba decidir qué hacer en caso de fallo. Por ejemplo:
-texto que se le pase no se corresponda con un formato válido de fecha, lanzará una excepción. Pero justamente en el método no tenemos muy +
-claro que hacer puesto que dicho método lo utilizarán desde diferentes localizaciones del código en la aplicación. Por eso es mejor que +
-lancemos fuera la excepción para que sea quién utilice este método quién deba decidir qué hacer en caso de fallo. Por ejemplo:+
  
-\begin{lstlisting}[language=java]+<code java>
 public class Ventana { public class Ventana {
     . . .     . . .
Line 108: Line 107:
     }     }
 } }
-\end{lstlisting}+</code>
  
 ==== Bloque try-catch-finally ==== ==== Bloque try-catch-finally ====
  
-Se puede añadir también un tercer bloque de código asociado a la parte \verb try  que permite añadir código que se ejecutará siempre, de +Se puede añadir también un tercer bloque de código asociado a la parte //try// que permite añadir código que se ejecutará siempre, de forma que incluso lo hará cuando se produzca una excepción no controlada. Normalmente se utiliza para la zona donde liberar recursos que hayan sido ocupados durante el bloque //try//. De esta forma nos aseguramos que siempre se liberen correctamente, incluso aunque el flujo de ejecución del código se vea interrumpido por una excepción.
-forma que incluso lo hará cuando se produzca una excepción no controlada. Normalmente se utiliza para la zona donde liberar recursos que +
-hayan sido ocupados durante el bloque \verb try . De esta forma nos aseguramos que siempre se liberen correctamente, incluso aunque el flujo +
-de ejecución del código se vea interrumpido por una excepción.+
  
-\begin{lstlisting}[language=java]+<code java>
 . . . . . .
 BufferedReader buffer = null; BufferedReader buffer = null;
Line 142: Line 138:
 } }
 . . . . . .
-\end{lstlisting}+</code>
  
 ==== Cómo crear tus propias excepciones ==== ==== Cómo crear tus propias excepciones ====
  
-Como ya hemos visto, Java tiene una serie de \emph{unchecked\emph{checked exceptionsque son lanzadas en determinadas situaciones. +Como ya hemos visto, Java tiene una serie de //unchecked// //checked exceptions// que son lanzadas en determinadas situaciones. Vamos a ver ahora cómo también podemos crear nuestras propias excepciones y lanzarlas cuando se produzcan situaciones de "más alto nivel" en nuestra lógica de la aplicación.
-Vamos a ver ahora cómo también podemos crear nuestras propias excepciones y lanzarlas cuando se produzcan situaciones de "más alto nivel" en +
-nuestra lógica de la aplicación.+
  
 Por ejemplo, en una aplicación para la gestión de inventarios, almacenes o pedidos, podemos definir una excepción como la del siguiente ejemplo, para que sea lanzada en el caso de que se termine el stock de algún producto de nuestro almacén: Por ejemplo, en una aplicación para la gestión de inventarios, almacenes o pedidos, podemos definir una excepción como la del siguiente ejemplo, para que sea lanzada en el caso de que se termine el stock de algún producto de nuestro almacén:
  
-\begin{lstlisting}[language=java]+<code java>
 public class FueraDeStockException extends Exception { public class FueraDeStockException extends Exception {
  
Line 163: Line 157:
     }     }
 } }
-\end{lstlisting}+</code>
  
 Así, cuando nos encontramos con esa situación, podemos directamente lanzar nuestra excepción: Así, cuando nos encontramos con esa situación, podemos directamente lanzar nuestra excepción:
  
-\begin{lstlisting}[language=java]+<code java>
 . . . . . .
 private void anadirProductoAlCarrito(Producto producto) { private void anadirProductoAlCarrito(Producto producto) {
Line 175: Line 169:
 } }
 . . . . . .
-\end{lstlisting}+</code>
  
 Y de esta manera, por ejemplo, en el controlador o interaz de la aplicación, podríamos hacer algo así: Y de esta manera, por ejemplo, en el controlador o interaz de la aplicación, podríamos hacer algo así:
  
-\begin{lstlisting}[language=java]+<code java>
 public class Ventana { public class Ventana {
     . . .     . . .
Line 192: Line 186:
     . . .     . . .
 } }
-\end{lstlisting}+</code>
  
 ==== Bloques multi-catch ==== ==== Bloques multi-catch ====
  
-También es posible capturar más de un tipo de excepción bajo un mismo bloque \verb catch , aunque no es una práctica recomendada ya que no +También es posible capturar más de un tipo de excepción bajo un mismo bloque //catch//, aunque no es una práctica recomendada ya que no permite afinar el caso de error en algunos casos, pero bien utilizado permite que agrupemos en el caso de que varias excepciones tengan asociado el mismo bloque de código.
-permite afinar el caso de error en algunos casos, pero bien utilizado permite que agrupemos en el caso de que varias excepciones tengan +
-asociado el mismo bloque de código.+
  
-\begin{lstlisting}[language=java]+<code java>
 public class Ventana { public class Ventana {
     . . .     . . .
Line 213: Line 205:
     . . .     . . .
 } }
-\end{lstlisting}+</code>
  
 ==== Uso de recursos en bloques try-catch ==== ==== Uso de recursos en bloques try-catch ====
  
-Como hemos visto en el primer ejemplo, accedíamos a un fichero en la excepción, para luego acabar liberando los recursos al finalizar el +Como hemos visto en el primer ejemplo, accedíamos a un fichero en la excepción, para luego acabar liberando los recursos al finalizar el bloque //try-catch//. A veces es habitual que dichos recursos se inicialicen al comenzar la excepción (incluso dentro de ésta) y se liberen al terminar. Así, ese ejemplo podría escribirse de la siguiente forma:
-bloque \verb try-catch . A veces es habitual que dichos recursos se inicialicen al comenzar la excepción (incluso dentro de ésta) y se +
-liberen al terminar. Así, ese ejemplo podría escribirse de la siguiente forma:+
  
-\begin{lstlisting}[language=java]+<code java>
 . . . . . .
 try (BufferedReader buffer =  try (BufferedReader buffer = 
Line 237: Line 227:
 } }
 . . . . . .
-\end{lstlisting}+</code>
  
-Para este caso, hay que tener en cuenta que, para que Java pueda liberar automáticamente los recursos de una clase Java, debemos implementar +Para este caso, hay que tener en cuenta que, para que Java pueda liberar automáticamente los recursos de una clase Java, debemos implementar uno de los interfaces ''java.lang.AutoClosable'' ''java.io.Closable'', y declarar un método ''close()'':
-uno de los interfaces \verb java.lang.AutoClosable  \verb java.io.Closable , y declarar un método \verb close() :+
  
-\begin{lstlisting}[language=java]+<code java>
 public class MiRecurso implements AutoCloseable { public class MiRecurso implements AutoCloseable {
     . . .     . . .
Line 253: Line 242:
     }     }
 } }
-\end{lstlisting}+</code>
  
 ===== Aserciones ===== ===== Aserciones =====
  
-Las aserciones son sentencias utilizadas para comprobar si una condición es cierta (o no) y controlar asi los errores en el código. +Las aserciones son sentencias utilizadas para comprobar si una condición es cierta (o no) y controlar asi los errores en el código. Básicamente equivale a una sentencia ''if'' que evalúa una condición y genera una Excepción ''AssertException'' si ésta se cumple, mostrando el mensaje asociado a la misma. De forma similar a cómo hacen las excepciones, permite hacerlo de forma cómoda y sin romper el flujo del código. Además, estás condiciones en forma de aserción sólo tienen efecto si se pasa la opción ''-ea'' ''-enableassertions'' a la máquina virtual cuando se ejecuta la aplicación. De esta forma sólo se activan cuando es necesario o interesa utilizarlas.
-Básicamente equivale a una sentencia \verb if  que evalúa una condición y genera una Excepción \verb AssertException  si ésta se cumple, +
-mostrando el mensaje asociado a la misma. De forma similar a +
-cómo hacen las excepciones, permite hacerlo de forma cómoda y sin romper el flujo del código. Además, estás condiciones en forma de aserción +
-sólo tienen efecto si se pasa la opción \verb -ea  \verb -enableassertions  a la máquina virtual cuando se ejecuta la aplicación. De esta +
-forma sólo se activan cuando es necesario o interesa utilizarlas.+
  
 Veamos un ejemplo: Veamos un ejemplo:
  
-\begin{lstlisting}[language=java]+<code java>
 . . . . . .
 String cadena = "Esto es un texto"; String cadena = "Esto es un texto";
Line 276: Line 260:
 assertion cadena == null; assertion cadena == null;
 . . . . . .
-\end{lstlisting}+</code>
  
-Si ejecutamos el código anterior con la opción \verb -ea  activada como opción de la JVM, se nos mostrará el siguiente mensaje de error:+Si ejecutamos el código anterior con la opción ''-ea'' activada como opción de la JVM, se nos mostrará el siguiente mensaje de error:
  
-\begin{verbatim}+<code bash>
 run: run:
 Exception in thread "main" java.lang.AssertionError: La cadena es nula Exception in thread "main" java.lang.AssertionError: La cadena es nula
Line 286: Line 270:
 /Users/Santi/Library/Caches/NetBeans/8.2/executor-snippets/run.xml:53: Java returned: 1 /Users/Santi/Library/Caches/NetBeans/8.2/executor-snippets/run.xml:53: Java returned: 1
 BUILD FAILED (total time: 0 seconds) BUILD FAILED (total time: 0 seconds)
-\end{verbatim}+</code>
  
 ---- ----
  
-(c) 2019-2021 Santiago Faci+(c) 2019-{{date>%Y}} Santiago Faci
apuntes/excepciones.1615383448.txt.gz · Last modified: 2021/03/10 13:37 by Santiago Faci