1. Introducción
En este tutorial, cubriremos cómo crear una excepción personalizada en Java .
Mostraremos cómo se implementan y utilizan las excepciones definidas por el usuario para las excepciones marcadas y no marcadas.
2. La necesidad de excepciones personalizadas
Las excepciones de Java cubren casi todas las excepciones generales que están destinadas a suceder en la programación.
Sin embargo, a veces necesitamos complementar estas excepciones estándar con las nuestras.
Las principales razones para introducir excepciones personalizadas son:
- Excepciones de la lógica empresarial: excepciones que son específicas de la lógica empresarial y el flujo de trabajo. Estos ayudan a los usuarios de la aplicación o los desarrolladores a comprender cuál es el problema exacto
- Para detectar y proporcionar un tratamiento específico a un subconjunto de excepciones de Java existentes
Las excepciones de Java se pueden marcar y desmarcar. En las siguientes secciones, cubriremos ambos casos.
3. Excepción de verificación personalizada
Las excepciones marcadas son excepciones que deben tratarse explícitamente.
Consideremos un fragmento de código que devuelve la primera línea del archivo:
try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) return file.nextLine(); } catch(FileNotFoundException e) { // Logging, etc }
El código anterior es una forma clásica de manejar las excepciones comprobadas de Java. Si bien el código arroja FileNotFoundException, no está claro cuál es la causa exacta: si el archivo no existe o el nombre del archivo no es válido.
Para crear una excepción personalizada, tenemos que extender la clase java.lang.Exception .
Veamos un ejemplo de esto creando una excepción marcada personalizada llamada Excepción de nombre de archivo incorrecto:
public class IncorrectFileNameException extends Exception { public IncorrectFileNameException(String errorMessage) { super(errorMessage); } }
Tenga en cuenta que también tenemos que proporcionar un constructor que tome una cadena como mensaje de error y llame al constructor de la clase principal.
Esto es todo lo que necesitamos hacer para definir una excepción personalizada.
A continuación, veamos cómo podemos usar la excepción personalizada en nuestro ejemplo:
try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) return file.nextLine(); } catch (FileNotFoundException e) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException("Incorrect filename : " + fileName ); } //... }
Hemos creado y utilizado una excepción personalizada, por lo que el usuario ahora puede saber cuál es la excepción exacta. ¿Es suficiente? En consecuencia, estamos perdiendo la causa raíz de la excepción .
Para solucionar esto, también podemos agregar un parámetro java.lang.Throwable al constructor. De esta forma, podemos pasar la excepción raíz a la llamada al método:
public IncorrectFileNameException(String errorMessage, Throwable err) { super(errorMessage, err); }
Ahora, la excepción de nombre de archivo incorrecto se utiliza junto con la causa raíz de la excepción como esta:
try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) { return file.nextLine(); } } catch (FileNotFoundException err) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException( "Incorrect filename : " + fileName , err); } // ... }
Así es como podemos usar excepciones personalizadas sin perder la causa raíz por la que ocurrieron .
4. Excepción personalizada sin marcar
En nuestro mismo ejemplo, supongamos que necesitamos una excepción personalizada si el nombre del archivo no contiene ninguna extensión.
En este caso, necesitaremos una excepción personalizada sin marcar similar a la anterior, ya que este error solo se detectará durante el tiempo de ejecución.
Para crear una excepción personalizada sin marcar, necesitamos extender la clase java.lang.RuntimeException :
public class IncorrectFileExtensionException extends RuntimeException { public IncorrectFileExtensionException(String errorMessage, Throwable err) { super(errorMessage, err); } }
Por lo tanto, podemos usar esta excepción personalizada sin marcar en nuestro ejemplo:
try (Scanner file = new Scanner(new File(fileName))) { if (file.hasNextLine()) { return file.nextLine(); } else { throw new IllegalArgumentException("Non readable file"); } } catch (FileNotFoundException err) { if (!isCorrectFileName(fileName)) { throw new IncorrectFileNameException( "Incorrect filename : " + fileName , err); } //... } catch(IllegalArgumentException err) { if(!containsExtension(fileName)) { throw new IncorrectFileExtensionException( "Filename does not contain extension : " + fileName, err); } //... }
5. Conclusión
Las excepciones personalizadas son muy útiles cuando necesitamos manejar excepciones específicas relacionadas con la lógica empresarial. Cuando se usan correctamente, pueden servir como una herramienta útil para un mejor manejo y registro de excepciones.
El código de los ejemplos utilizados en este artículo está disponible en Github.