Library of prerequisites for throwing an IllegalArgumentException for checking notNull

Do you know a good alternative to Apache Commons Validate or Guava Preconditions that will throw an IllegalArgumentException instead of a NullPointerException when checking if the object is not null (except for Spring Assert )?


I know Javadocs say:

Applications should throw instances of this class [NullPointerException] to indicate other illegal uses of the null object.

However, I just don't like it. For me, NPE has always meant that I just forgot to get a null link somewhere. My eyes are so trained that I can notice that he is looking at the magazines at a speed of several pages per second, and if I do this, an error warning always appears in my head. Therefore, it would be completely incomprehensible to me that it be thrown when I expect an IllegalArgumentException.

Say I have a bean:

public class Person { private String name; private String phone; //.... } 

and service method:

 public void call(Person person) { //assert person.getPhone() != null //.... } 

In some context, it may happen that a person does not have a telephone (my grandmother has no one). But if you want to name such a person, for me it is a call to a call method with IllegalArgument . Look at the hierarchy - NullPointerException is not even a subclass of IllegalArgumentException. This basically tells you - again you tried calling getter on a null reference.

In addition, there have already been discussions and there is this good answer, which I fully support. So my question is - I need to do ugly things like this:

 Validate.isTrue(person.getPhone() != null, "Can't call a person that hasn't got a phone"); 

to have it in my opinion, or is there a library that just throws an IllegalArgumentException to check for notNull?

+5
source share
7 answers

Since the topic of this question has turned into the “Proper use of IllegalArgumentException and NullpointerException” , I would like to point out a direct travel answer in “Effective Java Article 60” (second edition):

Perhaps all erroneous method calls come down to an illegal argument or an illegal state, but other exceptions are usually used for certain types of illegal arguments and conditions. If the caller skips null in any parameter for which null values ​​are prohibited, the convention dictates that a NullPointerException is thrown and not an IllegalArgumentException . Similarly, if the caller misses an out-of-band value in a parameter representing the index in the sequence, an IndexOutOfBoundsException should be thrown, not an IllegalArgumentException.

+4
source

What about checkArgument ?

 public void call(Person person) { Preconditions.checkArgument(person.getPhone() != null); // cally things... } 

checkArgument throws IllegalArgumentException instead of NullPointerException .

+3
source

You can use valid4j with hamcrest-matchers (found on Maven Central as org.valid4j: valid4j). The Validation class supports regular input validation (i.e., throws recoverable exceptions):

 import static org.valid4j.Validation.*; validate(argument, isValid(), otherwiseThrowing(InvalidException.class)); 

References:

In a note: this library also supports preconditions and post-conditions (for example, statements), and you can register your own global policy if necessary:

 import static org.valid4j.Assertive.*; require(x, greaterThan(0)); // throws RequireViolation extends AssertionError ... ensure(r, notNullValue()); // throws EnsureViolation extends AssertionError 
+1
source

Take a look at https://bitbucket.org/cowwoc/requirements (I am the author). You can override the default exception type using withException() as follows:

 new Verifiers().withException(IllegalArgumentException.class).requireThat(name, value).isNotNull(); 
+1
source

Not that I knew. I just collapse my own to get the right behavior with a brief call, mimicking a Guava implementation, but setting up the type of exception.

 class Preconditionz { public static <T> T checkNotNull(T reference, Object errorMessage) { if (reference == null) { throw new IllegalArgumentException(String.valueOf(errorMessage)); } return reference; } } 

I like to continue and import static these very commonly used methods, so you can call them very concisely.

 import static com.whatever.util.Preconditionz.checkNotNull; // ... public void call(Person person) { checkNotNull(person, "person"); checkNotNull(person.getPhone(), "person.phone"); // ... } 

Depending on your environment, you may call it checkNotNull2 , so it’s easier for you to add import through autocomplete to your IDE or let you use it with the standard checkNotNull .

0
source

I think I learned something here again, because thanks to the wonderful comments by Olivier Grigorey, Louis Wassermann, Collind and Captain Man. Standards are usually a strong and sufficient reason, since they do that ordinary programmers will always understand correctly, but in this particular case I had little doubt that perhaps this rule, established around NPE, is not too good. Java is an old language, and some of its functions turned out to be a bit unsuccessful (I don’t want to speak incorrectly, it may be too strong a judgment) - for example, checked exceptions , although you may also disagree. Now I think this doubt is resolved, and I should:

  • Throw an IllegalArgumentException when, in a specific context, I can say why a null value is wrong, and not from a business perspective. For example, in the service method public void call(Person person) I know what it means that the system has a phone number.
  • Throw a NullPointerException when I just know that a null value is wrong here and sooner or later will throw a NullPointerException, but in the specific context, I don't know what this means from a business perspective. An example is the immutable collections of Guavas. When you build one and try to add a null value element, it throws you an NPE. He does not understand what this value means to you, it is too general, but he simply knows that it is wrong, so he decides to report it immediately, with a more appropriate message, so that you can more efficiently recognize the problem.

Keeping in mind, I would say that the best option, so that the statement in the public void call(Person person) example would look like Captain Man, suggests:

 Preconditions.checkArgument(person.getPhone() != null, "msg"); 

Checking an argument is a good name for this method - it’s clear that I am checking whether the business contract matches the argument to person, and it’s clear that I am expecting an IllegalArgumentException if it does not. This is a better name than Validate.isTrue from Apache Commons. On the other hand, saying Validate.notNull or Preconditions.checkNotNull suggests that I check for a null reference and I really expect NPE.

Thus, the final answer will be: there is no such beautiful library and should not be the way it would be confused. (And Spring Assembler should be fixed).

0
source

You can easily do this:

 if (person.getPhone() == null) { throw new IllegalArgumentException("Can't call a person that hasn't got a phone"); } 

For other programmers, it’s clear what you mean and does exactly what you want.

-1
source

All Articles