TL;DR Just use Lombok's @SneakyThrows
.
Christian Hujer has already explained in detail why throwing checked exceptions from a stream is, strictly speaking, not possible due to Java's limitations.
Some other answers have explained tricks to get around the limitations of the language but still being able to fulfil the requirement of throwing "the checked exception itself, and without adding ugly try/catches to the stream", some of them requiring tens of additional lines of boilerplate.
I am going to highlight another option for doing this that IMHO is far cleaner than all the others: Lombok's @SneakyThrows
. It has been mentioned in passing by other answers but was a bit buried under a lot of unnecessary detail.
The resulting code is as simple as:
public List<Class> getClasses() throws ClassNotFoundException {
List<Class> classes =
Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
.map(className -> getClass(className))
.collect(Collectors.toList());
return classes;
}
@SneakyThrows // <= this is the only new code
private Class<?> getClass(String className) {
return Class.forName(className);
}
We just needed one Extract Method
refactoring (done by the IDE) and one additional line for @SneakyThrows
. The annotation takes care of adding all the boilerplate to make sure that you can throw your checked exception without wrapping it in a RuntimeException
and without needing to declare it explicitly.