-
Notifications
You must be signed in to change notification settings - Fork 8
How it works
For each functional interface Foo
usable in Stream
s, this package defines an interface
ThrowingFoo
. For instance, here is the base code for the interface ThrowingFunction
:
@FunctionalInterface
public interface ThrowingFunction<T, R>
extends Function<T, R>
{
R doApply(T t)
throws Throwable;
@Override
default R apply(T t)
{
try {
return doApply(t);
} catch (Error | RuntimeException e) {
throw e;
} catch (Throwable throwable) {
throw new ThrownByLambdaException(throwable);
}
}
}
Note that it extends the base interface; any implementation (class, method reference, lambda...) is therefore also usable as the base type.
The Chainer
class is the basic abstract class which is implemented for all throwing functional interfaces; for an interface Foo
:
- the chainer implementation is called
FooChainer
, - it implements
ThrowingFoo
(thereforeFoo
as well).
A sample use would be:
// Return a ToLongFunctionChainer<Path>; return a default value if the function fails:
final ToLongFunction<Path> f = Throwing.toLongFunction(Files::size).orReturn(OL);
A Chainer
implementation defines three methods:
-
orTryWith()
: if the first throwing instance fails, try with another throwing instance; this returns aChainer
, therefore you can chain other instances from there; -
orThrow()
: throw an exception on failure; you'll have to specify an unchecked exception class which has a constructor accepting a singleThrowable
as an argument; -
fallbackTo()
: invoke a non throwing version of the functional interface on failure; -
sneakyThrow()
: uses the same trick as lombok's@SneakyThrows
annotation to rethrow the exception thrown as is, even if checked.
In addition, implementations provide other methods depending on the type of the functional interface implemented. FunctionChain
, for instance, provides .orReturn()
; ConsumerChain
provides .orDoNothing()
; etc etc.
You can implement your own version of a chainer for your own functional interfaces, or interfaces provided by the JDK which are not covered by this package. Recall that a Chainer
implementation should implement the throwing version of the interface!
In addition, you can extend the Throwing
class so as to add the matching method to invoke instances of your new Chainer
implementation.