为什么Scanner使用Scanner#ioException()而不是抛出异常?

时间:2014-12-03 05:30:28

标签: java java.util.scanner ioexception

这有什么好处/垮台吗?

通常,从流中读取时会抛出异常:

try {
    inputStream.read();
}catch(IOException e) {
    e.printStackTrace();
}

但是当使用Scanner时,您不会被迫处理异常。相反,如果抛出一个,则使用Scanner#ioException()

我知道Scanner不是一个流,而不是一个在需要时解析数据的tokenizer,但为什么它处理它的异常与其他涉及IO的行为不同?我什么时候应该以这种方式处理异常?

1 个答案:

答案 0 :(得分:5)

class documentation for java.util.Scanner给出了解释。

  

扫描程序可以从任何实现Readable接口的对象读取文本。如果对底层可读的Readable.read(java.nio.CharBuffer)方法的调用抛出IOException,则扫描程序会假定已到达输入的结尾。可以通过ioException()方法检索底层可读引发的最新IOException。

Scanner是较低级别I / O阅读器的更高级别的使用者,并处理异常本身。如果您需要/需要ioException() method会使该例外 。在某些构造函数之外,Scanner API的行为是明确定义的,无需调用者捕获任何与I / O相关的异常。

好处是调用者不需要编写try / catch块或使自己的方法抛出 checked IOException类型。这是可能的,因为Scanner实现已经以不需要exceptions as flow control的方式处理这些边缘情况。

如果相反,Scanner方法抛出一个已检查的异常,那么如果您有合理的方法从异常情况中恢复,那么您作为调用者应该只编写一个catch块。实际上,你将强制来编写它,或者,如果你没有抓住它,现在你的类 API变得“污染”,声明它的方法抛出已检查的异常仅仅因为实现细节(因为你碰巧使用 Scanner类)。

另一方面,低级Readable接口及其实现无法处理异常情况,并且强制将它们抛给调用者;他们无法知道“正确”的恢复手段是什么,或者是否存在任何合适的手段。抛出已检查的异常可能是必要的,但优秀的API会尽可能避免使用它。