17

I am writing codes that query the database to get the data. There are some classes that consist of Lists, but sometime the list or other attribute can not be initiated and their value is null, so I need to write list!=null || list.isEmpty or attribute != null, before I can use the attribute.

Unfortunately, it easy to forget it, and I really think it is ugly to do it every time when I operate an attribute. I am going to write some code to explain it.

public class SpotVo {
    private Double avg;

    private String brief;

    private ArrayList<HotelVo> hotels;

    private int id;

    private ArrayList<byte[]> images;

    private AddressVo location;

    private String name;

    private ArrayList<RestaurantVo> restaurants;
}

As you can see, there are some lists and other attributes in this class, there can all be null or empty, can I do something to avoid it?

acdcjunior
  • 132,397
  • 37
  • 331
  • 304
ssj
  • 1,737
  • 2
  • 16
  • 28
  • 1
    I think the best way to avoid this kind of ugly code is to always write short, simple, concise methods that only perform one basic task. If you do this, you can generally perform one clean null-check at the top of each method and exit immediately if something important is null. I had a professor in school that told us "_every function you write should be less than 60 lines_". That was some of the best advice I ever got. – jahroy May 25 '13 at 02:21
  • 1
    @jahroy *"every method should be less than 60 lines"* amen, brother. – acdcjunior May 25 '13 at 02:23
  • I have learned an other edition that kick a man who write a method has 10 lines out of you term. – ssj May 25 '13 at 02:28
  • 4
    @ssj ^^ I wish I could make sense out of that comment... – jahroy May 25 '13 at 02:54
  • @jahroy - You might be happier if you don't understand it. – Hot Licks May 25 '13 at 03:16
  • @HotLicks can't agree more – ssj May 25 '13 at 03:21

4 Answers4

5

The answer depends on whether null has a special meaning. For example for a String field does your application need to distinguish between null and ""? For a Collection-valued field does it need to distinguish between null and an empty collection object?

If the answer is "no", then you could write your "data object" classes to normalize the nulls to the respective "in band" values. You could do this in the getters or the setters or the constructors, depending on exactly how the objects are materialized from the database.

A couple of other things you could do are:

  • Change the database schema to make the respective columns "not null".

  • If you are using an ORM or a data binding mechanism, try to configure that (via annotations or whatever) to use the "in band" values instead of null.

The point of turning null into "" or an empty array or collection is that you don't need to treat the "in band" value as a special case ... unless the business logic of your application specifically requires this.

In short, if you stamp out the null values systematically, you don't need to test for them in the business logic.


Note that this approach doesn't always work. The case that annoys me is fetching parameters from an HTTPRequest object in a servlet:

  • The application potentially has to deal with 4 distinct cases:

    • parameter not present

    • parameter present with no value / an empty value

    • parameter present with a non-empty value

    • parameter present multiple times.

  • The parameters are being fetched from a standard API rather than a custom class that could be made to normalize the values according to the webapp's requirements.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    I think you are right,I should control it from the source. – ssj May 25 '13 at 02:57
  • I think that too since this technique will save you from sending objects or nulls for no reason in case if nulls or "" for Strings – Youans May 25 '13 at 03:41
1

The easiest way to solve this is with CollectionUtils.isEmpty.

Returns: true if empty or null

This way you can do it in one line.

When it comes to "attributes", there are design patterns that can help with this. Or, you can use Guava's Optional class. You can read more about it here: What's the point of Guava's Optional class

Community
  • 1
  • 1
Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356
0

You can write a function that checks if an object is null and/or if it's a String, is it "". Then simply call that function each time you would need to check all of the conditions. Make it return a boolean so that you can just insert it in the if statements.

boolean check(Object o)
{
    if (o != null)
        {
            if (o instanceof String)
            {
                if (((String) o).equals(""))
                    return false;
            }
            return true;
        }
        return false;
}

Refer to rcook's suggestion in the comments for a better implementation of this.

Steve P.
  • 14,489
  • 8
  • 42
  • 72
  • but I can not write a function for every class that i used in my app. – ssj May 25 '13 at 02:15
  • check my edit. It will work for all Objects (all of your defined classes implicitly extend Object). If you have any other special cases for specific Objects, other than String, you can insert them in the function. – Steve P. May 25 '13 at 02:17
  • 3
    Instead of using instanceof, have one method for Object and one for String. Let the compiler decide which one to call and save your runtime an if statement... boolean isEmpty(Object o) { return (o == null); } (something additional needed for collections) – arcy May 25 '13 at 02:31
0

I think there's two problems here: One is that you have to check for null values which I absolutely agree is stupid. The problem is that null is a native to the Java language, so the only way to make it slightly nicer is to use methods like the ones mentioned by Steve P and tieTYT. There is however another way of dealing with null by never using it. Of course you cannot completely avoid it, but at least in your own code you should eliminate all null-references. There are a few great arguments for that which I won't cover here, but you can read Avoiding != null statements for more details.

If you're interested a Java-based language, Scala, have developed this nicely by implementing an Option class that can tell whether a value exists or does not (equal to the null value). Nice blog post about it here: http://jim-mcbeath.blogspot.fr/2008/10/avoiding-nulls.html

Having (mostly) stowed the null-issue away, the next problem will be to check for isEmpty or similar when using collections. This is, as you say, a pain in the arse. But I've actually found that these checks can be largely avoided. It all depends on what you need to do with your collection of course, but in most cases collections are used for traversing or manipulation in some way. Using the foreach-loop in Java will make sure nothing is performed if nothing is in the collection. Neat.

There are some cases where a collection must not be empty. Some of these can be avoided though, by having a good design (for instance one that allows empty lists, ensures that no list are empty etc.), but, for the rest of them there are simply no way around. Ever. But, having eliminated the null-checks, calling a few isEmpty now and then isn't that bad :-)

Hope that helped.

Community
  • 1
  • 1
Jens Egholm
  • 2,730
  • 3
  • 22
  • 35