Unfortunately you can't do this. Declared exceptions are part of a method's signature and while you can narrow them e.g.
interface FooCallable extends Callable<T> {
T call() throws IOException; // Narrows Exception from the parent interface
}
you can't introduce new throws clauses or widen the declared one.
Iterator
is a fundamental Java interface, used by enhanced for, so even if somehow you could do what you wanted, the compiler would need to know that
for (T obj: ioExceptionThrowingIterable) { ... }
requires the checked IOException
to be caught or thrown.
It's matter of opinion, but I think you should use a custom subclass of RuntimeException
and document your interface carefully. Checked exceptions are avoided in modern frameworks, e.g. Spring, because of the problems associated with them.
Edit: Borrowed and adapted from user949300's answer, you could wrap the returned object in e.g.
interface RemoteObject<T> {
T get() throws IOException
}
Then return an Iterator<RemoteObject<T>>
, and force the caller to handle the IOException
when unwrapping with get
:
for (RemoteObject<Foo> obj: iterable) {
try {
foo = obj.get()
} catch (IOException ex) {
/*
* 9 times out of 10, the lazy user just prints the stack trace
* or something else inappropriate
* which is why I despise checked exceptions
*/
}
}
In this case, there's no need to extend Iterator
, it can be used directly. In fact, you can use Collection
, if applicable.