有时候,我们可以定义一个"空对象"来代替null,这样可以更加优雅的处理对象为null的情况,避免空指针异常。例如定义二叉树结点的时候,可以用一个NullNode结点来定义空结点。那么一个叶子结点的左子树和右子树就都可以指向NullNode,从而避免了可能引起空指针异常的null。
类图:
代码:
/** * * Interface for binary tree node. * */ public interface Node { String getName(); int getTreeSize(); Node getLeft(); Node getRight(); void walk(); }
/** * * Implementation for binary tree's normal nodes. * */ public class NodeImpl implements Node { private static final Logger LOGGER = LoggerFactory.getLogger(NodeImpl.class); private final String name; private final Node left; private final Node right; /** * Constructor */ public NodeImpl(String name, Node left, Node right) { this.name = name; this.left = left; this.right = right; } @Override public int getTreeSize() { return 1 + left.getTreeSize() + right.getTreeSize(); } @Override public Node getLeft() { return left; } @Override public Node getRight() { return right; } @Override public String getName() { return name; } @Override public void walk() { LOGGER.info(name); if (left.getTreeSize() > 0) { left.walk(); } if (right.getTreeSize() > 0) { right.walk(); } } }
/** * * Null Object implementation for binary tree node. *
* Implemented as Singleton, since all the NullNodes are the same. * */ public final class NullNode implements Node { private static NullNode instance = new NullNode(); private NullNode() {} public static NullNode getInstance() { return instance; } @Override public int getTreeSize() { return 0; } @Override public Node getLeft() { return null; } @Override public Node getRight() { return null; } @Override public String getName() { return null; } @Override public void walk() { // Do nothing } }