2

I use code object != null to avoid NullPointerException. Is there a good alternative to solve this as follow ?

if (someobject != null) {
    someobject.doCalc();
}

This will not work for NullPointerException, when it is unknown that if the object is null or not.

  • This is a different scenario. – Chaminda Bandara Apr 9 '18 at 8:42
  • 2
    But the rationale is the same. – Laiv Apr 9 '18 at 8:49
  • 2
    I would say it's not your responsibility to check if the object is null, "someobject" should never be created and returned null. Somewhere you have a code smell, check your design. – PmanAce Apr 9 '18 at 15:53
  • 1
    It is a project practice question. Along the same line as Kilian Foth's answer, I would say that the software architect for the project must decide whether to allow or forbid (or conditionally allow) nulls to be used in the entire code base, as a matter of policy. Once the project is full of code embodying this decision, the nullfulness becomes a foregone conclusion, one that cannot be changed. – rwong Mar 19 '19 at 18:13
5

The dilemma

If a variable with null value gets used in your program causing a NullPointerException, this is clearly a situation in your program which you did not expect. You must ask yourself the question: "Did I not expect it because I didn't take into consideration the possibility of a null value or did I assume the value could never be null here?"

If the answer is the latter, the problem isn't because you didn't handle the null value. The problem happened earlier, and you're only seeing the consequence of that error on the particular line it's used. In this case, simply adding a if (variable != null) isn't going to cut it. You'll wind up skipping lines you were supposed to execute because the variable was null, and you'll ultimately hit a line further on where you again assumed it wouldn't be null.

When null should be used

As a general rule, return null only when "absent" is a possible return value. In other words, your data layer may search for a record with a specific id. If that record isn't found, you can either throw an exception or simply return null. You may do either, but I prefer not to throw exceptions in situations where the strong possibility exists. So you return null instead of a value.

The caller of this method, presumably written by you, knows the possibility exists that the record may not exist and checks for null accordingly. There is nothing wrong with this in this case, though you should handle this possibility as soon as possible as otherwise everywhere in your program you will need to deal with the possibility of a null value.

Conclusion

In other words, treat null as a legitimate value, but deal with it immediately rather than wait. Ideally in your program, you should ever only have to check if it is null once in your program and only in the place where such a null value is handled.

For every value you expect to be non-null, you need not add a check. If it is null, accept that there is an error in your program when it was instantiated. In essence, favor fail fast over fail safe.

  • Is there a reason why you didn't consider the use of Optional? – lrxw Sep 26 '18 at 9:07
  • 2
    @Irxw Because it's a technical solution to a non-technical problem. If it is an error that the value is null, using Optional avoids the NullPointerException, but it doesn't fix your problem. You simply avoided the error associated with the problem. I'm aware of the existence of Optional, but I don't think this would have been a solution, though perhaps it was worth mentioning at least. – Neil Sep 26 '18 at 9:31
  • I think dealing with null is in generel a technical problem. In the non-technical world you don't have null. If you return an Optional just in case a value can be null, you also have the benefit to know that it won't be null if you don't use Optional as a return type :) – lrxw Sep 26 '18 at 13:29
8

Deciding whether or not null is a allowed as an object value is a decision that you must make consciously for your project.

You don't have to accept a language construct just because it exists; in fact, it is often better to enforce a strict rule against any nullvalues in the entire project. If you do this, you don't need checks; if a NullPointerException ever happens, that automatically means that there is a defect in your code, and it doesn't matter whether this is signalled by a NPE or by some other sanity check mechanism.

If you can't do this, for instance because you have to interoperate with other libraries that allow null, then you do have to check for it. Even then it makes sense to keep the areas of code where null is possible small if possible. The larger the project, the more sense it makes to define an entire "anti-corruption layer" with the only purpose of preserving stricter value guarantees than is possible elsewhere.

6

In Java 8, a new feature was added: Optional<>. This is for fields that may or may not be there and is an alternative to using null checks.

If you use Optional, then you can check whether or not it is present by calling isPresent(), i.e.

Optional<String> optionalString = Optional.of("Some string");
if (optionalString.isPresent()){
  System.out.println(optinalString.get());
}

Optional<String> optionalString2 = Optional.ofNullable(null);
System.out.println(optionalString2.orElse("Some other string"));

See the docs at https://docs.oracle.com/javase/10/docs/api/java/util/Optional.html.

This means that only Optionals are allowed to have no value, if there is a null anywhere else that is an error and should be allowed to throw a NPE, although external libraries may still return null and those should be checked.

  • 5
    This is just changing the check from != null to .isPresent(). That does not make your code tidier or move the check to the place where an object is created where it belongs. – Bent Apr 9 '18 at 9:51
  • 4
    @Bent: It does, however, allow you to remove the checks entirely for anything that isn't an Optional, because if you're using it properly, then only Optionals are allowed to not have a value now, so anything else that's null is broken and should be allowed to trigger the inevitable NPE. Granted, the answer doesn't mention that... :P – cHao Apr 9 '18 at 14:37
  • Using ifPresent, when possible, is even better since it performs the null-check and the get operation within the same call thus prevents any accidental get on an empty optional. – Joel Apr 9 '18 at 16:46
  • @cHao and that holds as long as everyone adheres to it, theoretically. In practice, even your Optional can be null. Optionals are a nice way to "mark" something as possibly null by business logic. They don't prevent accidental nulls that you might want to avoid. And you can only ensure they are consistently used as far as you have control over your project, e.g. you would need to wrap any 3rd party code. Optionals can be helpful, but they make way more sense in languages that revert the model, i.e. by design nothing can be null unless it's an optional. For Java it's just tacked on. – Frank Hopkins Mar 20 '19 at 0:58
  • @FrankHopkins: By the time an "accidental null" occurs, your program is already off the rails. != null won't make it do the right thing. Frankly, with or without Optional, the best course of action is to let the code try to use that null and trigger a NPE. Any "accidental null" is by definition a programming error, and should be fixed rather than swept under the rug. – cHao Mar 20 '19 at 3:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.