快速业务通道

诊断Java代码: 空标志错误模式 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-19

诊断Java代码: 空标志错误模式

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

空标志错误模式

在我的上一篇文章中,我说明了用空指针代替各种不同基本类型的数据是如何成为引起 NullPointerException 异常最普遍的原因之一的。这一次,我将说明用空指针代替异常情况怎么也会导致问题的出现。在 Java 程序中,异常情况通常是通过抛出异常,并在适当的控制点捕获它们来进行处理。但是经常看到的方法是通过返回一个空指针值来表明这种情况(以及,可能打印一条消息到 System.err )。如果调用方法没有明确地检查空指针,它可能会尝试丢弃返回值并触发一个空指针异常。

您可能会猜想,之所以称这种模式为空标志错误模式,是因为它是不一致地使用空指针作为异常情况的标志引起的。

起因

让我们来考虑一下下面的这个简单的桥类(从 BufferedReaders 到 Iterators ):

import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.Iterator; public class BufferedReaderIterator implements Iterator {   private BufferedReader internal;   public BufferedReaderIterator(BufferedReader _internal) {    this.internal = _internal;   }   public boolean hasNext() {    try {     boolean result = true;     // Let''s suppose that lines in the underlying input stream are known     // to be no greater than 80 characters long.     internal.mark(80);     if (this.next() == null) {      result = false;     }     internal.reset();     return result;    }    catch (IOException e) {     System.err.println(e.toString());     return false;    }   }   public Object next() {    try {     return internal.readLine();    }    catch (IOException e) {     System.err.println(e.toString());     return null;    }   }   public void remove() {    // This iterator does not support the remove operation.    throw new UnsupportedOperationException();   } }

诊断Java代码: 空标志错误模式(2)

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

因为这个类作为 Iterator 接口的桥接实现,代码必须从 BufferedReader 捕获 IOException 异常。每一种方法通过返回某个缺省值来处理 IOException 。对于 hasNext ,返回 false 值。这是合理的,因为如果 IOException 异常被抛出,客户就不应该指望能从 Iterator 检索到另一个元素。另一方面,在 IOException 异常(因为它取决于 internal.readLine() 的返回值)和 internal 是空的情况下, next 都返回 null 。但这不是 Iterator 对象的客户所期待的。正常情况下,在没有更多元素的 Iterator 上调用 next 时,会抛出一个 NoSuchElementException 异常。如果我们的 Iterator 的客户依赖于这种行为,它很可能会尝试丢弃从调用 next 返回的空指针,结果导致 NullPointerException 异常。

不管 NullPointerException 异常什么时候出现,都要对如上所述的情况作检查。这种错误模式的出现很普遍。

预防措施

尽管这种错误模式经常出现,使用空标志仍是非常没有根据的(与上例的情况一样)。让我们来重写 next ,使它如我们期望的一样抛出 NoSuchElementException 异常:

public Object next() {    try {     String result = internal.readLine();     if (result == null) {    throw new NoSuchElementException();     }     else {    return result;     }    }    catch (IOExcepti

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号