English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
En este tutorial, aprenderás a manejar excepciones en Java utilizando ejemplos. Para manejar excepciones, usaremos el bloque try ... catch ... finally.
En el tutorial anterior, aprendimos sobre excepciones. Las excepciones son eventos inesperados que ocurren durante la ejecución del programa.
En Java, usamos componentes de manejo de excepciones try, catch y bloque finally para manejar excepciones.
Para capturar y manejar excepciones, colocamos el bloque de código try...catch...finally alrededor del código que puede generar excepciones. El bloque finally es opcional.
La sintaxis de try...catch...finally es:
try {}} // Código catch (ExceptionType e) { // Bloque de captura } finally { //Bloque finally }
El código que puede generar excepciones se coloca dentro del bloque try.
Debería haber un bloque catch o finally después de cada bloque try. Cuando ocurre una excepción, será capturada por el bloque que sigue.
El bloque catch no se puede usar solo, debe seguir inmediatamente al bloque try.
class Main { public static void main(String[] args) { try {}} Ejemplo de bloque finally 5 / int divideByZero = System.out.println("el resto del código del bloque try"); 0; { catch (ArithmeticException e) { + System.out.println("ArithmeticException => "); } } }
System.out.println("El bloque finally siempre se ejecuta");
Resultados de salida / ArithmeticException =>
En este ejemplo
En el bloque try, dividimos el número por cero. Esto produce una ArithmeticException.
Cuando ocurre una excepción, el programa salta el resto del código del bloque try.
Aquí, creamos un bloque catch para manejar ArithmeticException. Por lo tanto, ejecutamos las instrucciones dentro del bloque catch.
Si todas las instrucciones del bloque try no generan excepciones, se salta el bloque catch.
Para cada bloque try, puede haber cero o más bloques catch.
El tipo de parámetro de cada catch indica el tipo de excepción que se puede manejar. Los múltiples bloques catch nos permiten manejar cada excepción de manera diferente.
class ListOfNumbers { public int[] arrayOfNumbers = new int[10]; public void writeList() { try {}} arrayOfNumbers[10]] = 11; catch (NumberFormatException e1) { System.out.println("NumberFormatException => " + e1.getMessage()); } catch (IndexOutOfBoundsException e2) { System.out.println("IndexOutOfBoundsException => "); + e2.getMessage()); } } } class Main { public static void main(String[] args) { ListOfNumbers list = new ListOfNumbers(); list.writeList(); } }
System.out.println("El bloque finally siempre se ejecuta");
IndexOutOfBoundsException => Índice 10 fuera de límites para la longitud 10
En este ejemplo, declaramos un array de tamaño10 的整数数组arrayOfNumbers。
de un array de enteros arrayOfNumbers.}}10Sabemos que los índices de array siempre comienzan en 0. Por lo tanto, cuando intentamos asignar un valor a la índice9.
Se produce IndexOutOfBoundsException al asignar un valor, ya que los límites del array arrayOfNumbers son 0 a
Cuando ocurre una excepción en el bloque try
La excepción se lanza al primer bloque catch. El primer bloque catch no maneja la excepción IndexOutOfBoundsException, por lo que se pasa al siguiente bloque catch.
Java Bloque Finally
Para cada bloque try, solo se puede tener un bloque finally.
El bloque finally es opcional. Pero, si se define, siempre se ejecutará (incluso si no ocurre una excepción).
Si ocurre una excepción, se ejecuta después del bloque try...catch. Si no ocurre ninguna excepción, se ejecuta después del bloque try.
try {}} //code } catch (TipoException1 e1) { // La sintaxis básica del bloque finally es: } catch (TipoException1 e2) { // La sintaxis básica del bloque finally es: } finally { //catch }
class Main { public static void main(String[] args) { try {}} Ejemplo de bloque finally 5 / int divideByZero = 0; { catch (ArithmeticException e) { + System.out.println("ArithmeticException => "); } finally { e.getMessage()); } } }
System.out.println("El bloque finally siempre se ejecuta");
Resultados de salida / ArithmeticException => por cero
El bloque finally siempre se ejecuta
En este ejemplo, dividiremos un número por cero. Esto provoca una ArithmeticException capturada por el bloque catch, y el bloque finally siempre se ejecuta.
Usar el bloque finally se considera una buena práctica. Esto se debe a que contiene código de limpieza importante, como
Código que puede ser saltado accidentalmente con sentencias return, continue o break
Cerrar archivos o conexiones
Hemos mencionado que finally siempre se ejecuta, generalmente de esta manera. Pero, en ciertos casos, el bloque finally no se ejecuta:
Se produjo una excepción en el bloque finally
La hilera se ha detenido
Vamos a dar un ejemplo, intentamos crear un nuevo archivo usando FileWriter y escribir datos con PrintWriter.
import java.io.*; class ListOfNumbers { private int[] list = new int[10]; public ListOfNumbers() { //Almacenar valores enteros en el array de lista for (int i = 0; i < 10; i++) { list[i] = i; } } } public void writeList() { PrintWriter out = null; try {}} System.out.println("Entrar en la sentencia try"); //Crear un nuevo archivo OutputFile.txt out = new PrintWriter(new FileWriter("OutputFile.txt")); //Escribir los valores del array de lista en el archivo recién creado for (int i = 0; i < 10; i++) { out.println("Valor en: "); + i + " = " + list[i]; } } catch (IndexOutOfBoundsException e1) { System.out.println("IndexOutOfBoundsException => "); + e1.getMessage()); } catch (IOException e2) { System.out.println("IOException => "); + e2.getMessage()); } finally { //Verificar si PrintWriter está abierto if (out != null) { System.out.println("Cerrar PrintWriter"); out.close(); } else { System.out.println("PrintWriter no se puede abrir"); } } } } class Main { public static void main(String[] args) { ListOfNumbers list = new ListOfNumbers(); list.writeList(); } }
Al ejecutar este programa, pueden ocurrir dos posibilidades:
Se produce una excepción dentro del bloque try
El bloque try se ejecuta normalmente
Puede ocurrir una excepción al crear un nuevo FileWriter. Si no se puede crear o escribir el archivo especificado, se lanzará IOException.
Cuando ocurre una excepción, obtendremos la siguiente salida.
Entrar en la instrucción try IOException => OutputFile.txt PrintWriter no se puede abrir
Cuando no se produce ninguna excepción y el bloque try se ejecuta correctamente, obtendremos la siguiente salida.
Entrar en la instrucción try Cerrar PrintWriter
Se creará un archivo OutputFile.txt y contendrá lo siguiente
Value at: 0 = 0 Value at: 1 = 1 Value at: 2 = 2 Value at: 3 = 3 Value at: 4 = 4 Value at: 5 = 5 Value at: 6 = 6 Value at: 7 = 7 Value at: 8 = 8 Value at: 9 = 9
Vamos a intentar entender en detalle el flujo de manejo de excepciones con la ayuda del ejemplo anterior.
La imagen de arriba describe el flujo de ejecución del programa cuando se produce una excepción al crear un nuevo FileWriter.
Para encontrar el método que produjo la excepción, el método main llama al método writeList(), que a su vez llama al método FileWriter() para crear un nuevo archivo OutputFile.txt.
Cuando se produce una excepción, el sistema de tiempo de ejecución salta el resto del código del bloque try.
Empieza a buscar en orden inverso la pila de llamadas para encontrar el programa de manejo de excepciones adecuado.
Aquí, FileWriter no tiene programas de manejo de excepciones, por lo que el sistema de tiempo de ejecución verifica el siguiente método en la pila de llamadas, es decir, writeList.
El método writeList tiene dos programas de manejo de excepciones: uno para manejar IndexOutOfBoundsException y otro para manejar IOException.
Luego, el sistema procesa estos programas de manejo en el orden en que se produjeron.
En este ejemplo, el primer programa de manejo trata IndexOutOfBoundsException. Esto no coincide con el IOException lanzado por el bloque try.
Por lo tanto, se verifica qué programa de manejo de IOException es el siguiente. Si coincide con el tipo de excepción lanzada, se ejecutará el código del bloque catch correspondiente.
Después de ejecutar el programa de manejo de excepciones, se ejecutará el bloque finally.
En este escenario, debido a que se produjo una excepción en FileWriter, el objeto PrintWriter out nunca se abrió, por lo que no es necesario cerrarlo.
Ahora, supongamos que al ejecutar el programa no se produjo ninguna excepción y el bloque try se ejecutó correctamente. En este caso, se creará y se escribirá un archivo OutputFile.txt.
Es bien conocido que la ejecución del bloque finally no tiene relación con el manejo de excepciones. Debido a que no se produjo ninguna excepción, PrintWriter se abrió y necesita cerrarse. Esto se realiza mediante la sentencia out.close() en el bloque finally.
Desde Java SE 7Desde la versión superior, ahora podemos capturar más de un tipo de excepción con un solo bloque catch.
De esta manera, se puede reducir la repetición de código y aumentar la simplicidad y eficiencia del código.
Cada tipo de excepción que se puede manejar con el bloque catch se separa por un guión vertical (|).
Su sintaxis es:
try {}} // code } catch (TipoException1 | TipoException2 ex) { // bloque catch }
Para obtener más información, visiteJava captura múltiples excepciones.
try-with-La sentencia resources es una sentencia try que tiene una o más declaraciones de recursos.
Su sintaxis es:
try (declaración de recurso) { // uso del recurso } catch (ExceptionType e1) { // bloque catch }
Los recursos son objetos que deben cerrarse al finalizar el programa. Deben declararse e inicializarse dentro de la sentencia try.
Vamos a dar un ejemplo.
try (PrintWriter out = new PrintWriter(new FileWriter("OutputFile.txt"))) { // uso del recurso }
try-with-La sentencia resources también se conoce comoGestión de recursos automática. Esta sentencia cierra automáticamente todos los recursos al final de la sentencia.
Para obtener más información, visiteJava try-with-Sentencia resources.