3

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. Instead, if one is thrown, you would use 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? When should I handle exceptions in this manner?

Dioxin
  • 13,042
  • 5
  • 35
  • 70

1 Answers1

5

The explanation is given by the class documentation for java.util.Scanner.

A scanner can read text from any object which implements the Readable interface. 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. The most recent IOException thrown by the underlying readable can be retrieved via the ioException() method.

The Scanner is a higher level consumer of the lower level I/O reader and handles the exception itself. The ioException() method makes that exception available if you want/need it. Outside of certain constructors, the behavior of the Scanner API is well-defined without requiring the caller to catch any I/O-related exceptions.

The benefit is that the caller need not write try/catch blocks or make their own methods throw the checked IOException type. This is possible because the Scanner implementation is already handling those edge cases in a way that doesn't require exceptions as flow control.

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. 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).

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; 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.

Community
  • 1
  • 1
William Price
  • 3,677
  • 1
  • 30
  • 46