...
This noncompliant code example returns a null
ArrayList
when the size of the ArrayList
is 0. The class Inventory
contains a getStock()
method that constructs a list of items that have 0 inventory and returns the list of items to the caller. When the size of this list is 0, a null
is returned with the assumption that the client will install the necessary checks. Here, the client omits the check, causing a NullPointerException
at runtime.
Code Block | ||
---|---|---|
| ||
class Inventory { private final Hashtable<String, Integer> items; public Inventory() { items = new Hashtable<String, Integer>(); } public List<String> getStock() { List<String> stock = new ArrayList<String>(); Enumeration itemKeys = items.keys(); while(itemKeys.hasMoreElements()) { Object value = itemKeys.nextElement(); if((items.get(value)) == 0) { stock.add((String)value); } } if(items.size() == 0) { return null; } else { return stock; } } } public class Client { public static void main(String[] args) { Inventory inv = new Inventory(); List<String> items = inv.getStock(); System.out.println(items.size()); // Throws an NPE } } |
When the size of this list is 0, a null
is returned with the assumption that the client will install the necessary checks. Here, the client omits the check, causing a NullPointerException
at runtime.
Compliant Solution
This compliant solution eliminates the null
return and simply returns the List
, even when it is zero-length. The client can handle this situation effectively without being interrupted by runtime exceptions. When returning arrays rather than collections, take care to ensure that the client avoids attempts to access individual elements of a zero-length array. This prevents an ArrayOutOfBoundsException
.
Code Block | ||
---|---|---|
| ||
class Inventory { private final Hashtable<String, Integer> items; public Inventory() { items = new Hashtable<String, Integer>(); } public List<String> getStock() { List<String> stock = new ArrayList<String>(); Integer noOfItems; // Number of items left in the inventory Enumeration itemKeys = items.keys(); while(itemkeys.hasMoreElements()) { Object value = itemKeys.nextElement(); if((noOfItems = items.get(value)) == 0) { stock.add((String)value); } } return stock; // Return list (possibly zero-length) } } public class Client { public static void main(String[] args) { Inventory inv = new Inventory(); List<String> items = inv.getStock(); System.out.println(items.size()); // Does not throw an NPE } } |
The client can handle this situation effectively without being interrupted by runtime exceptions. When returning arrays rather than collections, take care to ensure that the client avoids attempts to access individual elements of a zero-length array. This prevents an ArrayOutOfBoundsException
.
Compliant Solution
This compliant solution returns an empty list, which is an equivalent, permissible technique:.
Code Block | ||
---|---|---|
| ||
public List<String> getStock() { List<String> stock = new ArrayList<String>(); Integer noOfItems; // Number of items left in the inventory Enumeration itemkeys = items.keys(); while(itemkeys.hasMoreElements()) { Object value = itemKeys.nextElement(); if((noOfItems = items.get(value)) == 0) { stock.add((String)value); } } if(l.isEmpty()) { return Collections.EMPTY_LIST; // Always zero-length } else { return stock; // Return list } } // Class Client ... |
...