Перейти к основному содержимому

IllegalArgumentException или NullPointerException для нулевого параметра?

· 4 мин. чтения

1. Введение

Среди решений, которые мы принимаем при написании наших приложений, многие касаются того, когда генерировать исключения и какой тип генерировать.

В этом кратком руководстве мы рассмотрим вопрос о том, какое исключение генерировать, когда кто-то передает нулевой параметр одному из наших методов: IllegalArgumentException или NullPointerException .

Мы изучим тему, изучив аргументы обеих сторон.

2. Исключение нелегального аргумента

Во-первых, давайте посмотрим на аргументы для создания исключения IllegalArgumentException .

Давайте создадим простой метод, который генерирует исключение IllegalArgumentException при передаче значения null :

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

Теперь давайте перейдем к аргументам в пользу IllegalArgumentException .

2.1. Это то, как Javadoc говорит об использовании

Когда мы читаем Javadoc для IllegalArgumentException , там говорится, что он используется, когда в метод передается недопустимое или недопустимое значение . Мы можем рассматривать нулевой объект как недопустимый или неуместный, если наш метод этого не ожидает, и это было бы подходящим исключением для нас.

2.2. Это соответствует ожиданиям разработчиков

Далее давайте подумаем о том, что мы, как разработчики, думаем, когда видим трассировку стека в наших приложениях. Очень распространенный сценарий, в котором мы получаем исключение NullPointerException , — это случайная попытка доступа к нулевому объекту. В этом случае мы собираемся пройти как можно глубже в стек, чтобы увидеть, на что мы ссылаемся, что является null .

Когда мы получаем IllegalArgumentException , мы, вероятно, предположим, что передаем что-то неправильное в метод. В этом случае мы будем искать в стеке самый нижний метод, который мы вызываем, и оттуда начнем нашу отладку. Если мы рассмотрим этот способ мышления, IllegalArgumentException приведет нас в наш стек ближе к тому месту, где совершается ошибка.

2.3. Другие аргументы

Прежде чем мы перейдем к аргументам для NullPointerException , давайте посмотрим на пару более мелких аргументов в пользу IllegalArgumentException . Некоторые разработчики считают, что NullPointerException должен вызывать только JDK . Как мы увидим в следующем разделе, Javadoc не поддерживает эту теорию. Другой аргумент заключается в том, что более последовательно использовать IllegalArgumentException , поскольку это то, что мы использовали бы для других недопустимых значений параметров.

3. Исключение NullPointerException

Далее рассмотрим аргументы для NullPointerException .

Давайте создадим пример, который генерирует исключение NullPointerException :

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

3.1. Это то, как Javadoc говорит об использовании

Согласно Javadoc для NullPointerException , NullPointerException предназначен для использования при попытке использовать null там, где требуется объект . Если параметр нашего метода не должен быть null , то мы могли бы разумно рассматривать его как требуемый объект и генерировать исключение NullPointerException .

3.2. Это совместимо с API JDK

Давайте задумаемся о многих распространенных методах JDK, которые мы вызываем во время разработки. Многие из них выдают исключение NullPointerException , если мы указываем значение null . Кроме того, Objects.requireNonNull() генерирует исключение NullPointerException , если мы передаем значение null. Согласно документации Objects , он существует в основном для проверки параметров.

В дополнение к методам JDK, которые выдают NullPointerException , мы можем найти другие примеры определенных типов исключений, выбрасываемых из методов в API коллекций. ArrayList.addAll(index, Collection) выдает исключение IndexOutOfBoundsException , если индекс выходит за пределы размера списка, и выдает исключение NullPointerException , если коллекция имеет значение null . Это два очень специфических типа исключений, а не более общий IllegalArgumentException .

Мы могли бы считать , что IllegalArgumentException предназначено для случаев, когда у нас нет доступного нам более конкретного типа исключения.

4. Вывод

Как мы видели в этом уроке, это вопрос, на который нет четкого ответа. Документация для двух исключений, похоже, перекрывается в том смысле, что, если их рассматривать по отдельности, они оба звучат уместно. Существуют также дополнительные убедительные аргументы для обеих сторон, основанные на том, как разработчики выполняют отладку, и на шаблонах, наблюдаемых в самих методах JDK.

Какое бы исключение мы ни выбрали, мы должны быть последовательными во всем нашем приложении. Кроме того, мы можем сделать наши исключения более полезными, предоставив значимую информацию конструктору исключений. Например, наши приложения будет проще отлаживать, если мы укажем имя параметра в сообщении об исключении.

Как всегда, код примера доступен на GitHub .