简体   繁体   English

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

[英]Why does Scanner use Scanner#ioException() instead of throwing the exception?

Is there any benefits/downfalls to this? 有什么好处/缺点吗?

Usually, you would throw an exception when reading from a stream: 通常,从流中读取时会抛出异常:

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

But when using a Scanner , you are not forced to handle the exception. 但是,使用Scanner ,您不必强制处理异常。 Instead, if one is thrown, you would use Scanner#ioException() . 相反,如果抛出一个,则应使用Scanner#ioException()

I know Scanner isn't a stream, rather than a tokenizer that parses data if needed, but why does it handle it's exceptions unlike other actions involving IO? 我知道Scanner不是流,而是令牌解析器,如果需要的话,该令牌解析器会解析数据,但是为什么它处理异常是不同于其他涉及IO的操作的呢? When should I handle exceptions in this manner? 我什么时候应该以这种方式处理异常?

The explanation is given by the class documentation for java.util.Scanner . 该解释由java.util.Scanner类文档给出。

A scanner can read text from any object which implements the Readable interface. 扫描程序可以从任何实现Readable接口的对象中读取文本。 If an invocation of the underlying readable's Readable.read(java.nio.CharBuffer) method throws an IOException then the scanner assumes that the end of the input has been reached. 如果对底层可读对象的Readable.read(java.nio.CharBuffer)方法的调用引发IOException,则扫描程序将假定已到达输入的结尾。 The most recent IOException thrown by the underlying readable can be retrieved via the ioException() method. 可以通过ioException()方法检索由底层可读内容引发的最新IOException。

The Scanner is a higher level consumer of the lower level I/O reader and handles the exception itself. Scanner是较低级别的I / O读取器的较高级别的使用者,并且可以处理异常本身。 The ioException() method makes that exception available if you want/need it . 如果需要,可以使用ioException()方法使该异常可用。 Outside of certain constructors, the behavior of the Scanner API is well-defined without requiring the caller to catch any I/O-related exceptions. 在某些构造函数之外,Scanner API的行为是明确定义的,而无需调用方捕获任何与I / O相关的异常。

The benefit is that the caller need not write try/catch blocks or make their own methods throw the checked IOException type. 好处是调用者无需编写try / catch块或使自己的方法抛出检查的 IOException类型。 This is possible because the Scanner implementation is already handling those edge cases in a way that doesn't require exceptions as flow control . 这是可能的,因为Scanner实施已经以不需要异常作为流控制的方式来处理这些极端情况。

If instead the Scanner methods were to throw a checked exception, you as the caller should only write a catch block if you have a reasonable way of recovering from the exceptional case. 取而代之的是,如果Scanner方法将引发一个已检查的异常,则您只有在您有合理的方法可以从例外情况中恢复时,您才应调用catch块。 Indeed, you'd be forced to write it or, if you didn't catch it, now your class API becomes "polluted" by declaring its methods to throw checked exceptions merely because of an implementation detail (because you happen to use the Scanner class). 确实,您被迫编写它,或者,如果您没有抓住它,现在您的类 API会因为声明其方法仅由于实现细节而引发被检查的异常而被“污染”(因为您碰巧使用了Scanner类)。

On the other hand, the lower-level Readable interface, and its implementations, have no way of handling exceptional cases and are forced to throw them to the caller; 另一方面,较低级别的Readable接口及其实现无法处理异常情况,因此不得不将它们扔给调用方; they have no way of knowing what the "correct" means of recovery is, or if any suitable means exists. 他们无法知道恢复的“正确”手段是什么,或者是否存在任何合适的手段。 Throwing checked exceptions can be necessary, but good APIs will try to avoid it where possible. 抛出检查异常可能是必要的,但是好的API会在可能的情况下尽量避免这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM