快速业务通道

诊断Java代码: 悬挂复合错误类型 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-07-04
}    else {     throw new NoSuchElementException();    }   }   public LinkedList getRest() {    if (! (this.isEmpty())) {     return this.rest;    }    else {     throw new NoSuchElementException();    }   }   public void addFirst(Object o) {    LinkedList oldThis = (LinkedList)this.clone();    this.first = o;    this.rest = oldThis;   }   public boolean isEmpty() {    return this.first == null && this.rest == null;   }   private Object clone() {    return new LinkedList(this.first, this.rest);   }

注意,两个读取器采取的行动依赖于是否链表为空。这正好是那种一个正确构建的类层次所要防止的 if-then-else 链。由于这些链,我们不用在一个单一类型的链表上孤立地考虑这些读取器。此外,如果在将来的某一天,我们需要第三种类型的链表(例如一个不可变的链表),我们将不得不重新编写每一个方法的代码。

但是真正简单的方法是我们怎样才能轻易地避免将错误引入到程序中。按照这种方法,清单 2 中的 LinkedList 的执行只能是可怜的失败。实际上,就象我前面提到的,我们的 LinkedList 类已经包含一个微小的但有破坏性的错误(你发现了吗?)。空链表的表示到底是什么呢?我前面说过,空链表就是两个域都包含一个空指针的 LinkedList 。实际上,零参数构造器就是建立一个这样的空链表。但是注意单参数构造器 不是把空链表放入到 rest 域,这是构建一个只有一个值的链表所必须的。相反,它是用空指针替代。由于悬挂复合类型错误将空指针和基本例的位置标记符相混淆,象这样的错误是很容易犯的。为了了解这错误怎样表明自己是一个空指针异常,让我们为清单写一个 equals 方法:

清单 3. 哪里错了

public boolean equals(Object that) {    // If the objects are not of the same class, then they are not equal.    // Reflection is used in case this method is called from an instance of a    // subclass.     if (this.getClass() == that.getClass()) {    LinkedList _that = (LinkedList)that;     if (this.isEmpty() || _that.isEmpty()) {    return this.isEmpty() && _that.isEmpty();     }     else {    boolean firstEltsMatch = this.getFirst().equals(_that.getFirst());    boolean restEltsMatch = this.getRest().equals(_that.getRest());    return firstEltsMatch && restEltsMatch;     }    }    else {     return false;    }   }

诊断Java代码: 悬挂复合错误类型(3)

时间:2011-02-11 IBM Eric E. Allen

如果 this 和 that 都是非空,那么 equals 方法可以正确地预计它能调用它们的 getFirst 和 getRest 而不出现错误信息。但是如果链表中的任意一个包含用单参数构造器建立的任何部分,那么,在一个空链应该等待的地方,这个递归调用将最终表示为一个空指针。当它调用 getFirst 或 getRest 时,一个空指针异常就出现了。

一种观点可能是简单地直接把空链表表示成空指针,但是这个想法完全不可行的,因为在那时,不可能去掉链表的最后一个元素和在空链表中插入一个元素。

另一方面,可以照下面的方法重写单参数构造器来修复错误:

清单 4. 修复错误

public LinkedList(Object _first) {    this.first = _first;    this.rest = new LinkedList();   }

但是,象大多数的错误类型一样,阻止它们的出现总比修补它们要好的多。修补错误使得代码很容易被打断,即使简单的读取器、设置器和 equals 方法都会变得庞大,

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号