2

Assume I've a class Order, which contains an Object Item, which in turn Contains an Object Category, which again Contains a String CategoryName.

Now, I want to extract the category name from these nested objects only if none of these intermediate objects are null.

class Order {
    Item item;
    public Item getItem() {
        return item;
    }
}
class Item {
    Category category;
    public Category getCategory() {
        return category;
    }
}
class Category {
    String categoryName;
    public String getCategoryName() {
        return categoryName;
    }
}

The code I usually end up writing is:

if (order != null && order.getItem() != null && order.getItem().getCategory() != null
        && order.getItem().getCategory().getCategoryName() != null) {
    System.out.println("Category Name is present and is " + order.getItem().getCategory().getCategoryName());
}

Is there a better way of checking this, instead of calling each of the getters again.
Like to check if getCategoryName() is null, I'll have to call getItem().getCategory() so I'm ending up calling these previous getters a lot of times when multiple objects are involved.

Another way is to create a variable of item after its null check, then create a variable of category and so on.

But is there a better way?

3 Answers3

2

Is there a better way of checking this,

Yes, use immutable objects and pass the values as Constructor parameters.

class Order {
    private final Item item;
  // check Item being not null _before_ creating an order object.
    public Order(Item item){ 
        this.item= item;
    }
    public Item getItem() {
        return item;
    }
}

This way the getter cannot return null.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
1

Try using Optional.ofNullable

Optional<String> optionalCategoryName = Optional.ofNullable(order).map(Order::getItem)
        .map(Item::getCategory).map(Category::getCategoryName);

if (optionalCategoryName.isPresent()) {
    System.out.println("Category Name is present and is " + optionalCategoryName.get());
}

You can use map and nest the sub-objects there by eliminating the need to call those previous getters again. It also makes your code look more readable.

Note : This works from Java 8 and for before I guess Guava Optional should work in similar fashion.

Kishore Bandi
  • 5,537
  • 2
  • 31
  • 52
0

You could always just get the category name for use and if the chain of calls to acquire it results in a null pointer exception, catch that exception right away and handle the situation. That way your code proceeds on the assumption that it's all going to work fine without wasting cycles checking, and then if something does happen it fails gracefully.

b4n4n4p4nd4
  • 70
  • 1
  • 10