Aeon
Aeon

Reputation: 87

Check method parameter for null or not?

I have a method which doesn't allow null as parameter. Should i check the parameter inside the method for null and throw a IllegalArgumentException? If yes, i would have to implement that check inside a lot of methods and it would look ugly. So what is the best way?

Upvotes: 2

Views: 10117

Answers (2)

BlueWizard
BlueWizard

Reputation: 372

I'm a bit late for the party but Java 1.7 added Objects#requireNonNull.

It's just a simple method which will throw a NullPointerException if the parameter is null. I personally like this much better than failing inside the logic itself, since the method not only fails fast but one doesn't need to guess in a multiple varibales-statement which of the variables was null.

The method returns the non-null value which is helpful for Setters and Constructors:

public Repot(Date reportDate, String message) {
    this.reportDate = Objects.requireNonNul(reportDate);
    this.message = Objects.requireNonNul(message);
}

Upvotes: 2

Robin Krahl
Robin Krahl

Reputation: 5308

Well, that’s a question of personal preference. I’d say: Yes, you should. It is a lot easier to debug if you throw an exception once you notice that there is a problem instead of getting an exception when you first access the object, maybe in an other method thousands of lines away. (But throw a NullPointerException instead of IllegalArgumentException.)

But you have to do this check manually. Of course, you can write a helper method or use Guava’s Preconditions:

public void test(final String string) {
    Preconditions.checkNotNull(string); // will throw a NullPointerException if string is null
}

Edit: Especially if you write an API to be used by others, it is helpful to tell the people whether you are expecting non-null values or whether null is okay. You can do so using the @Nullable, @Nonnull (both per variable or field), @ParametersAreNonnullByDefault and @ParametersAreNullableByDefault annotations (both per class, package or method) located in javax.annotation (not part of the JDK).

Edit 2: Okay, so why do I recommend to use a NPE instead of an IAE? First of all, it’s the standard way to handle this problem. The JDK does this, important libraries like Guava do this, and the one and only book about Java, Effective Java, recommends it (item 60). But I know, this is not a valid argument. In this answer mentioned by @fabian, @Jason Cohen argues in favor of a IAE. His arguments are:

  • Documentation/definition of the exceptions. Yes, there is a list of applicable cases. But the JavaDoc also states that it is not overall. In fact, it states that ‘Applications should throw instances of this class to indicate other illegal uses of the null object.’ That’s exactly what we do here.
  • Expectation of the stack trace reader. Firstly, I doubt that his assumption is true. If I see an IAE, I think of an illegal value. If I see a NPE, the problem is clear: null. Secondly, I don’t think that these expectations are a valid argument here. If everyone throws NPEs on null arguments, these expectations would change. And the fact that many people misunderstand a behaviour does not mean that it this behaviour wrong.
  • IAE being more appropriate. That’s a personal question. As said above, I think that the NPE is more appropriate as it indicates a null value. Since NPE is clearly designed to handle null values, why would you chose an IAE instead? ;)
  • No difference between null and illegal values. There is a difference. To be honest: I do not like this. I really appreciate Ceylon’s approach of null being the only instance of the Null class. (In my Java code, I usually use Guava’s Optional class to represent nullable variables.) But the Java authors made a clear decision: null is a very special thing, different from all other values. This is the reason why it should be handled differently – e. g. with a different exception. An IAE indicates that there is something wrong with a value: maybe too short, too long, negative, positive, zero. A NPE indicates that there simply is no value.

An other reason why I prefer the NPE is consistent behaviour. From the caller’s point of view – assuming that I do not know the method implementation – I have to assume that calling a method with a null argument will cause a NPE once this argument is accessed. Throwing a NPE on manual checking does not change this behaviour. It just improves the moment the exceptions is raised.

Furthermore, using NPEs allows me to omit the manual check in very simple methods, e. g.:

public void test(@Nonnull final String string) {
    string.toString();
}

Upvotes: 7

Related Questions