1. Tipos de excepciones

Todas las excepciones se dividen en 4 tipos, que son en realidad clases que se heredan unas a otras.
Clase Throwable
La clase base para todas las excepciones es la clase Throwable
. La clase Throwable
contiene el código que escribe la pila de llamadas actual (rastreo de pila del método actual) en una matriz. Aprenderemos qué es una pila de llamadas un poco más adelante.
El operador throw solo puede aceptar un objeto que se derive de la clase Throwable
. Y aunque teóricamente puedes escribir código como throw new Throwable();
, nadie suele hacer esto. El objetivo principal de la clase Throwable
es tener una única clase padre para todas las excepciones.
Clase Error
La siguiente clase de excepción es la clase Error
, que hereda directamente la clase Throwable
. La máquina Java crea objetos de la clase Error
(y sus descendientes) cuando se han producido problemas graves. Por ejemplo, un fallo de hardware, memoria insuficiente, etc.
Por lo general, como programador, no hay nada que puedas hacer en una situación en la que se ha producido un error de este tipo (el tipo para el que se debe lanzar un Error
) en el programa: estos errores son demasiado graves. Todo lo que puedes hacer es notificar al usuario de que el programa se está bloqueando y/o escribir toda la información conocida sobre el error en el registro del programa.
Clase Exception
Las clases Exception
y RuntimeException
son para errores comunes que ocurren en la operación de muchos métodos. El objetivo de cada excepción lanzada es ser capturada por un bloque catch
que sepa cómo manejarla adecuadamente.
Cuando un método no puede completar su trabajo por alguna razón, debe notificar de inmediato al método de llamada lanzando una excepción del tipo correspondiente.
In other words, if a variable is equal to null
, the method will throw a NullPointerException
. If the incorrect arguments were passed to the method, it will throw an InvalidArgumentException
. If the method accidentally divides by zero, it will throw an ArithmeticException
.
RuntimeException
class
RuntimeExceptions
son un subconjunto de Exceptions
. Podríamos decir que RuntimeException
es una versión más liviana de las excepciones comunes (Exception
) - se imponen menos requisitos y restricciones en dichas excepciones.
Aprenderá la diferencia entre Exception
y RuntimeException
más adelante.
2. Throws
: excepciones verificadas

Todas las excepciones de Java se dividen en 2 categorías: excepciones verificadas y excepciones no verificadas.
Todas las excepciones que heredan de RuntimeException
o Error
se consideran excepciones no verificadas. Todas las demás son excepciones verificadas.
Veinte años después de que se introdujeran las excepciones verificadas, casi todos los programadores de Java lo consideran un error. En los marcos modernos populares, el 95% de todas las excepciones son no verificadas. El lenguaje C#, que copió casi exactamente a Java, no agregó excepciones verificadas.
¿Cuál es la principal diferencia entre excepciones verificadas y no verificadas?
Las excepciones verificadas tienen requisitos adicionales impuestos sobre ellas. A grandes rasgos, son los siguientes:
Requisito 1
Si un método lanza una excepción verificada, debe indicar el tipo de excepción en su firma. De esa manera, cada método que lo llama es consciente de que esta "excepción significativa" puede ocurrir en él.
Indique excepciones verificadas después de los parámetros del método después de la palabra clave throws
(no use por error la palabra clave throw
). Se ve algo así:
type method (parameters) throws exception
Ejemplo:
checked exception | unchecked exception |
---|---|
|
|
En el ejemplo de la derecha, nuestro código lanza una excepción no comprobada - no se requiere ninguna acción adicional. En el ejemplo de la izquierda, el método lanza una excepción comprobada, por lo que se agrega la palabra clave throws
a la firma del método junto con el tipo de la excepción.
Si un método espera lanzar múltiples excepciones comprobadas, todas deben especificarse después de la palabra clave throws
, separadas por comas. El orden no es importante. Ejemplo:
public void calculate(int n) throws Exception, IOException
{
if (n == 0)
throw new Exception("n is null!");
if (n == 1)
throw new IOException("n is 1");
}
Requisito 2
Si llamas a un método que tiene excepciones revisadas en su firma, no puedes ignorar el hecho de que las lanza.
Debes capturar todas estas excepciones agregando bloques catch
para cada una, o agregándolas a una cláusula throws
para tu método.
Es como si dijéramos: "Estas excepciones son tan importantes que debemos capturarlas. Y si no sabemos cómo manejarlas, entonces debemos notificar a cualquiera que pueda llamar a nuestro método que tales excepciones pueden ocurrir en él.
Ejemplo:
Imagina que estamos escribiendo un método para crear un mundo poblado por humanos. El número inicial de personas se pasa como argumento. Por lo tanto, necesitamos agregar excepciones si hay muy pocas personas.
Creando la Tierra | Nota |
---|---|
|
El método potencialmente lanza dos excepciones checked:
|
Esta llamada al método se puede manejar de 3 formas:
1. No capturar ninguna excepción
Esto se hace con mayor frecuencia cuando el método no sabe cómo manejar adecuadamente la situación.
Código | Nota |
---|---|
|
El método que llama no maneja las excepciones y debe informar a otros sobre ellas: las agrega a su propia cláusula de throws . |
2. Capturar algunas de las excepciones
Manejamos los errores que podemos manejar. Pero los que no entendemos, los pasamos al método que llama. Para hacer esto, necesitamos agregar su nombre a la cláusula de throws:
Código | Nota |
---|---|
|
El llamador solo captura una excepción comprobada — LonelyWorldException . La otra excepción debe ser agregada a su firma, indicándola después de la palabra clave throws |
3. Captura todas las excepciones
Si el método no lanza excepciones al método llamador, entonces el método llamador siempre está seguro de que todo funcionó bien. Y no podrá tomar ninguna acción para solucionar situaciones excepcionales.
Código | Nota |
---|---|
|
Todas las excepciones son atrapadas en este método. El llamador estará seguro de que todo salió bien. |
3. Captura de múltiples excepciones
Los programadores odian duplicar código. Incluso han creado un principio de desarrollo correspondiente: DRY (No te repitas). Pero cuando se manejan excepciones, a menudo ocurre que un bloque try
está seguido por varios bloques catch
con el mismo código.
O puede haber 3 bloques catch
con el mismo código y otros 2 bloques catch
con otro código idéntico. Esta es una situación estándar cuando su proyecto maneja excepciones de manera responsable.
A partir de la versión 7, en el lenguaje Java se agregó la capacidad de especificar múltiples tipos de excepciones en un solo bloque catch
. Se ve aproximadamente así:
try
{
// Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
// Exception handling code
}
Puede tener tantos bloques catch
como desee. Sin embargo, un solo bloque catch
no puede especificar excepciones que hereden una de otra. En otras palabras, no puede escribir catch (Exception
| RuntimeException
e), porque la clase RuntimeException
hereda de Exception
.
GO TO FULL VERSION