有时候,我们可以定义一个"空对象"来代替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.
* <p>
* 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
}
}