Checked exceptions within Block<T>

Brian Goetz brian.goetz at oracle.com
Sat Jan 12 09:21:50 PST 2013


Or you could write your own trivial combinator: static<T> Block<T> exceptionWrappingBlock(Block<T> b) { return e -> { try { b.accept(e); } catch (Exception e) { throw new RTE(e); } }; } You can write it once, in less that the time it took to write your original e-mail. And similarly once for each kind of SAM you use. I'd rather we look at this as "glass 99% full" rather than the alternative. Not all problems require new language features as solutions. (Not to mention that new language features always causes new problems.) On 1/12/2013 11:03 AM, Zhong Yu wrote: > I too have this problem, since we have lots of code throwing checked > exceptions, it's a challenge to wrap them in functional interfaces > that do not throw. > > If the solution is to smuggle checked exception as unchecked, JDK > should provide a standard class for that specific purpose, or > everybody will be forced to invent their own. > > A better solution is probably having varying exceptions > > interface Block<T, E extends Throwable> > void apply(T input) throws E; > > <T,E extends Throwable> void forEach(Block<T,E> block) throws E > > this is very ugly though; I'd dream the language could make it simpler like > > interface Block<T> > void apply(T input) throws ?; > // abstract method; throws E; add E to interface. > > <T> void forEach(Block<T> block) throws ? { ... } > // non-abstract method; throws E; add E to method. > > > Zhong Yu > > On Fri, Jan 11, 2013 at 10:12 PM, Michael Hixson > <michael.hixson at gmail.com> wrote: >> 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