IllegalArgumentException o NullPointerException para un parámetro nulo?

1. Introducción

Entre las decisiones que tomamos mientras escribimos nuestras aplicaciones, muchas se refieren a cuándo lanzar excepciones y qué tipo lanzar.

En este tutorial rápido, vamos a abordar el problema de qué excepción lanzar cuando alguien pasa un parámetro nulo a uno de nuestros métodos: IllegalArgumentException o NullPointerException .

Exploraremos el tema examinando los argumentos de ambos lados.

2. IllegalArgumentException

Primero, veamos los argumentos para lanzar una IllegalArgumentException .

Creemos un método simple que arroje una IllegalArgumentException cuando se le pasa un nulo :

public void processSomethingNotNull(Object myParameter) { if (myParameter == null) { throw new IllegalArgumentException("Parameter 'myParameter' cannot be null"); } }

Ahora, pasemos a los argumentos a favor de IllegalArgumentException .

2.1. Así dice el Javadoc que se use

Cuando leemos el Javadoc para IllegalArgumentException , dice que se usa cuando se pasa un valor ilegal o inapropiado a un método . Podemos considerar que un objeto nulo es ilegal o inapropiado si nuestro método no lo espera, y esta sería una excepción apropiada para nosotros.

2.2. Coincide con las expectativas de los desarrolladores

A continuación, pensemos en cómo pensamos nosotros, como desarrolladores, cuando vemos rastros de pila en nuestras aplicaciones. Un escenario muy común en el que recibimos una NullPointerException es cuando accidentalmente intentamos acceder a un objeto nulo . En este caso, vamos a profundizar lo más que podamos en la pila para ver a qué estamos haciendo referencia que es nulo .

Cuando obtenemos una IllegalArgumentException , es probable que asumamos que estamos pasando algo incorrecto a un método. En este caso, buscaremos en la pila el método más bajo al que estamos llamando y comenzaremos nuestra depuración desde allí. Si consideramos esta forma de pensar, la IllegalArgumentException nos llevará a nuestra pila más cerca de donde se está cometiendo el error.

2.3. Otros argumentos

Antes de pasar a los argumentos para NullPointerException , veamos un par de puntos más pequeños a favor de IllegalArgumentException . Algunos desarrolladores sienten que solo el JDK debería lanzar NullPointerException . Como veremos en la siguiente sección, el Javadoc no apoya esta teoría. Otro argumento es que es más consistente usar IllegalArgumentException ya que eso es lo que usaríamos para otros valores de parámetros ilegales.

3. NullPointerException

A continuación, consideremos los argumentos de NullPointerException .

Creemos un ejemplo que arroje una NullPointerException :

public void processSomethingElseNotNull(Object myParameter) { if (myParameter == null) { throw new NullPointerException("Parameter 'myParameter' cannot be null"); } }

3.1. Así dice el Javadoc que se use

De acuerdo con el Javadoc para NullPointerException , NullPointerException está destinado a usarse para intentar usar null donde se requiere un objeto . Si nuestro parámetro de método no tiene la intención de ser nulo , entonces razonablemente podríamos considerar esto como un objeto requerido y lanzar la NullPointerException .

3.2. Es consistente con las API de JDK

Tomemos un momento para pensar en muchos de los métodos comunes de JDK que llamamos durante el desarrollo. Muchos de ellos lanzan una NullPointerException si proporcionamos un valor nulo . Además, Objects.requireNonNull () arroja una NullPointerException si pasamos null. Según la documentación de Objects , existe principalmente para validar parámetros.

Además de los métodos JDK que lanzan NullPointerException , podemos encontrar otros ejemplos de tipos de excepciones específicos que se lanzan desde métodos en la API de colecciones. ArrayList.addAll (index, Collection) arroja una IndexOutOfBoundsException si el índice está fuera del tamaño de la lista y arroja una NullPointerException si la colección es nula . Estos son dos tipos de excepción muy específicos en lugar de la IllegalArgumentException más genérica .

Podríamos considerar que IllegalArgumentException está destinado a los casos en los que no tenemos un tipo de excepción más específico disponible.

4. Conclusión

Como hemos visto en este tutorial, esta es una pregunta que no tiene una respuesta clara. La documentación de las dos excepciones parece superponerse en el sentido de que, cuando se toman solas, ambas parecen apropiadas. También hay argumentos convincentes adicionales para ambos lados basados ​​en cómo los desarrolladores realizan su depuración y en los patrones que se ven en los propios métodos JDK.

Cualquiera que sea la excepción que elijamos, debemos ser coherentes en toda nuestra aplicación. Además, podemos hacer que nuestras excepciones sean más útiles proporcionando información significativa al constructor de excepciones. Por ejemplo, nuestras aplicaciones serán más fáciles de depurar si proporcionamos el nombre del parámetro en el mensaje de excepción.

Como siempre, el código de ejemplo está disponible en GitHub.