Welcome 微信登录

首页 / 软件开发 / JAVA / 诊断Java代码: Double Descent错误模式

诊断Java代码: Double Descent错误模式2011-02-12 IBM Eric E. Allen不要强制转换这个类!

与可怕的 空指针异常(该异常除了报告空指针之外,对于将要发生的事情什么也不说)不同,类强制转换异常相对来说容易调试。

类强制转换经常发生在递归下行数据结构的程序中,通常是当代码的某些部分在每次方法调用中下行了两级且在第二次下行时调度不当时发生的。程序员可通过学习 Double Descent 错误模式来识别这种问题。

Double Descent 错误模式

本周的专题是 Double Descent 错误模式。它通过类强制转换异常来表明。它是由递归下行复合数据结构引起的,这种下行方式有时在一次递归调用中要下行多级。这样做经常需要添加类型强制转换来编译代码。但是,在这种下行中,很容易忘记检查是否满足了适当的不变量来保证这些类型强制转换成功。

考虑以下的 int 二元树的类层次结构。因为我们希望考虑到空树的情况,所以将不把 value 字段放入 Leaf 类中。由于这一决定使所有的 Leaf 相同,我们将用一个静态字段为 Leaf 保留一个单元素。

清单 1. int 二元树的类层次结构

abstract class Tree {
}
class Leaf extends Tree {
public static final Leaf ONLY = new Leaf();
}
class Branch extends Tree {
public int value;
public Tree left;
public Tree right;
public Branch(int _value, Tree _left, Tree _right) {
this.value = _value;
this.left = _left;
this.right = _right;
}
}

现在,假定我们希望在 Tree 上添加一个方法,该方法确定任意两个连贯的节点(比如一个分支和它的其中一个子分支)是否都包含一个 0 作为它们的值。我们可能添加以下方法(注意:最后一个方法将不以它的当前形式编译):

清单 2. 确定两个连贯的节点是否都包含值 0 的方法

// in class Tree:
public abstract boolean hasConsecutiveZeros();
// in class Leaf:
public boolean hasConsecutiveZeros() {
return false;
}
// in class Branch:
public boolean hasConsecutiveZeros() {
boolean foundOnLeft = false;
boolean foundOnRight = false;
if (this.value == 0) {
foundOnLeft = this.left.value == 0;
foundOnRight = this.right.value == 0;
}
if (foundOnLeft || foundOnRight) {
return true;
}
else {
foundOnLeft = this.left.hasConsecutiveZeros();
foundOnRight = this.right.hasConsecutiveZeros();
return foundOnLeft || foundOnRight;
}
}