IllegalArgumentException или NullPointerException за нулев параметър?

1. Въведение

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

В този кратък урок, ние ще се справят с проблема, което е изключение да се хвърлят, когато някой минава нулев параметър за един от нашите методи: IllegalArgumentException или NullPointerException .

Ще изследваме темата, като разгледаме аргументите и за двете страни.

2. IllegalArgumentException

Първо, нека разгледаме аргументите за хвърляне на 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 е, когато случайно сме се опитали да получим достъп до нулев обект. В този случай ще влезем възможно най-дълбоко в стека, за да видим какво референтно е, че е нула .

Когато получим IllegalArgumentException , вероятно ще приемем, че предаваме нещо погрешно на метод. В този случай ще потърсим в стека най-долния метод, който извикваме, и ще започнем нашето отстраняване на грешки от там. Ако разгледаме този начин на мислене, IllegalArgumentException ще ни отведе в нашия стек по-близо до мястото, където е допусната грешката.

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

Преди да преминем към аргументите за NullPointerException , нека разгледаме няколко по-малки точки в полза на IllegalArgumentException . Някои разработчици смятат, че само JDK трябва да хвърля NullPointerException . Както ще видим в следващия раздел, 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, когато се изисква обект . Ако нашият параметър на метода не е предназначен за нула , тогава можем разумно да разгледаме това като обект, който се изисква, и да хвърлим NullPointerException .

3.2. Това е в съответствие с JDK API

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

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

Бихме могли да считаме IllegalArgumentException за предназначен за случаи, когато нямаме по-специфичен тип изключение, който да ни е на разположение.

4. Заключение

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

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

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