Checked exceptions within Block<T>
Michael Hixson
michael.hixson at gmail.com
Fri Jan 11 20:12:23 PST 2013
This is a bit of feedback for the lambda snapshots. It's not really
suggesting any changes or reporting bugs, but rather describing
difficulties I had. Hopefully this is the right mailing list for this
sort of thing.
--------------------------------
An issue that came up repeatedly was that I wanted refactor code like this:
for (Value value : values) {
...
}
Into this:
values.forEach(value -> {
...
});
But I couldn't because the "..." could throw a checked exception. I
worked around this in two ways:
(a) Don't refactor the code.
(b) Change whatever is throwing the checked exception to throw a
runtime exception instead.
Option (a) was not so bad if my "values" object was an Iterable. It
was worse when my values were a Map, a Stream, or an Optional. To
compare:
for (Map.Entry<Key, Value> entry : values.entrySet()) {
Key key = entry.getKey();
Value value = entry.getValue();
...
}
values.forEach((key, value) -> {
...
});
for (Iterator iterator =
values.stream().filter(predicate).map(function).iterator();
iterator.hasNext();) {
Value value = iterator.next();
...
}
values.stream().filter(predicate).map(function).forEach(value -> {
...
});
Optional<Value> optionalValue = somethingThatGivesAnOptional();
if (optionalValue.isPresent()) {
Value value = optionalValue.get();
...
}
somethingThatGivesAnOptional().ifPresent(value -> {
...
});
In one case (really several cases that relied on the same utility)
that was enough to drive me to option (b).
Option (b) allowed me to use the new lambda goodness but made me
slightly uncomfortable. The utility in question could write values in
CSV format to an Appendable. Since Appendable can throw IOExceptions,
I initially had the utility methods throw IOException. To make it
lambda-friendly I changed all its methods to look like this:
try {
...
} catch (IOException e) {
throw new UncheckedIOException(e);
}
This was fine because I wasn't catching any IOExceptions that occurred
in the first place (this code was running in response to a web
request, and if an exception occurred the framework would handle it
and show an error page). But I felt that it made my CSV utility a
little more "dangerous" for general use. This is all sort of
hand-wavey, but I don't like that the utility now potentially throws
runtime exceptions when there's not a programmer error and when there
might be a reasonable way to recover. Plus it is additional code in
my utility class, and good thing it is my class and not someone
else's.
What I really wanted to do was leave in the checked exceptions *and*
use the lambda forEach/ifPresent forms.
-Michael
More information about the lambda-dev
mailing list