What are good light-weight design patterns for avoid nulls in Java?
Asked Answered
H

8

11

Obviously one of the greatest banes of Java programming is nulls and null-pointer exception. What design patterns are there that don't add too much to your code but reduce the problem of sand null-pointer exceptions?

Hemoglobin answered 6/2, 2012 at 15:21 Comment(5)
Do we really need a pattern for nullpointer check? Using something like commonsutil shouldn't be enough?Cholecyst
"Obviously one of the greatest banes"? NullPointerExceptions are one of the easiest-to-diagnose kind of problems.Harriman
@thinksteep, if you do it a lot and a good pattern can be established, then it is beneficial. This is especially true if the way it is normally handled is verbose.Hemoglobin
I'd especially like to avoid writing: if ((a!=null)&&(a.getB()!=null)&(a.getB().getC()!=null)){ //stuff }Hemoglobin
@MichaelBorgwardt it is easy to diagnose, but it is common and you end up adding many lines to your code to avoid it. In fact, it is probably the issue that requires the most additional code to address.Hemoglobin
B
11

Null Object pattern. Look at Optional class from google-guava library.

Their wiki has an article on using and avoiding nulls.

Berry answered 6/2, 2012 at 15:22 Comment(6)
I knew google-guava had a lot of excellent goodies. I didn't know it addressed this problem.Hemoglobin
how does Null Object pattern can reduce the problem of sand null-pointer exceptions ?Homemaker
@UmNyobe: If you have an object instead of null, you cannot get a NullPointerException.Harriman
yes, but if an extraordinary situation occurs, why should the program behave normally?Homemaker
@Joe: I just hope you're not setting yourself up for a world of hurt down the line. An application that silently bypasses error-states is a lot harder to troubleshoot than one that screams and kicks.Jyoti
@Pap You've already made your point elsewhere. If you read into this solution it is not one that lends itself to silently ignoring nulls, just to handling them better.Hemoglobin
E
3

Just get used to not returning null objects on your methods.

public MyObject bohemianRhapsody(){

   try {
       if(isThisTheRealLife())
           return new MyObject("is this just fantasy");
       else
           return new MyObject("caught in a landslide, no escape from reality");
   } catch(ExampleCatchableException e){
       return new MyObject(""); // instead of return null
   }
}

...
System.out.println(bohemianRhapsody()); // will never print null

Also (kind of) referred to as the Null-Object pattern.

Exceedingly answered 6/2, 2012 at 15:28 Comment(3)
This is not the Null-Object pattern. There is a difference between an empty string and null. The invoking code (you made this public afterall) might very reasonably want to make decisions based on whether what was returned was null or empty.Metallo
@GeorgeMauer, it could very reasonably use the result directly on the interface - in which case, is it better to show "null" or nothing?Exceedingly
@Exceedingly - Your update is closer to the Null-Object pattern. (Presumably) MyObject is going to be displayed in the interface by invoking ToString - you should return MyObject(null) and simply have ToString() return empty string in that special case. That way, invoking code can still check whether the result was null (using an IsNull() method perhaps) but will not get null exceptions. See the Nullable<> class in C# as a solid example.Metallo
H
3

Why do you want to avoid null pointer exception? Getting null when expecting something else it is one of the first indications something is wrong when you write code. Things like Null Object Pattern should be use when you are sure it is adequate. One of the biggest disadvantages of design pattern are their abuse\misuse.

EDIT:

I think the best way to reduce null return will be to increase usage of exceptions. Think about a List returning a null object when you try to access to the element at index -1, you will be using things like

if( list.get(-1).equals(nullObject))

which is even worse. I believe it is better to raise an exception when the arguments are either unexpected or incompatibles.

Homemaker answered 6/2, 2012 at 15:31 Comment(1)
More checked exceptions are preferable to null pointers. I don't like null pointers because they indicate something is wrong, but they do at RUN-TIME. Something like Null Object Pattern is better, because your code is tracking the error and can provide a logical antidote to the problem.Hemoglobin
D
3

There are some helpfull annotations designed for thiese purposes by IntellyJ: @Nullable and @NotNull
Detecting probable NPE’s

Dowlen answered 1/2, 2013 at 19:36 Comment(0)
J
2

I guess it's a matter of taste, but I would say that the greatest banes of languages like Smalltalk/Objective-C is that they DON'T have null and that there AREN'T any NullPointerExceptions. I'm not a fan of "Null object pattern", in fact I detest it with passion as I find it makes troubleshooting and finding bugs so much harder without any real benefit. Null has a meaning (often bad) and should not be treated like any other generic state.

Like has been mentioned in this thread, NPE are really powerful and a good way to catch syntactical errors or bad coding early on and if (obj != null) is pretty straight-forward. If your application starts generating NPE at runtime, you've done something wrong and you need to fix it. Don't try to hide the exception, fix whatever it is that is CAUSING the exception.

Jyoti answered 6/2, 2012 at 15:34 Comment(3)
Null pointer exception is an unchecked exception. So the problem is that you won't know the problem until runtime. It is far better is your code is written to address having no value for something in the first place.Hemoglobin
Of course. That is why you check for null-ness. What i find scary though, is when a value can be null without causing a clear and proper reaction (like an NPE). The whole "null is also an object" idea in Smalltalk/Obj-c I find simply appalling. Null is not a value, it is null.Jyoti
But what about a null-object that encapsulates that there is an error and even throws checked exceptions when it is used after it should be set. The problem with checking for nullness, is that we are human and can forget to do it. Null basically breaks the Java Object model. If you don't feel you need a language that holds your hand and reminds you to do things, you'd be more productive in a language that has weaker typing than Java.Hemoglobin
D
2
"something definetly not null".equals(maybeNullVar)

vs

maybeNullVar.equals("something definetly not null")
Dowlen answered 1/2, 2013 at 19:50 Comment(0)
L
1

These methods (see also Apache commons-lang) can reduce the burden of null checks in the cases of String processing by encapsulating them in methods that preserve semantic meaning of code:

public static boolean isBlank(final String str)
{
    return (str == null) || str.isEmpty();
}

public static boolean isNotBlank(final String str)
{
    return !StringUtils.isBlank(str);
}

public static boolean isEqual(final String s1, final String s2)
{
    if (s1 == s2) { return true; }
    if ((s1 == null) || (s2 == null)) { return false; }
    return s1.equals(s2);
}

public static boolean isNotEqual(final String s1, final String s2)
{
    return !StringUtils.isEqual(s1, s2);
}
Langobardic answered 15/6, 2015 at 2:41 Comment(0)
G
1

You don't have to use any design pattern.

Just initialize variables during declaration.

e.g.

List<String> names = new ArrayList<String>();
Map<String,String> pairs = new HashMap<String,String>();
Griffie answered 28/9, 2016 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.