Callable throws Exception, Runnable doesn't.
Is there anything standard that looks like
@FunctionalInterface
public interface TypedBlock<E extends Exception> {
public void run() throws E;
}
No, there is no built in functionality as I know. But you can use an external library for that (and many other cool features).
You can either use JOOL, where you can use the Unchecked class for this.
The example from there page demonstrates this with an IOException
Arrays.stream(dir.listFiles()).forEach(
Unchecked.consumer(file -> { System.out.println(file.getCanonicalPath()); })
);
Another (and in my opinion better) approach would be to use a functional designed library like Functionaljava.
A good approach would be to wrap your task in a Validation to decide afterwards, if the result was successful. This could look like this:
TypedBlock<IOException> foo = ...;
// do your work
final Validation<IOException, Unit> validation = Try.f(() -> {
foo.run();
return Unit.unit(); // Unit equals nothing in functional languages
})._1();
// check if we got a failure
if (validation.isFail()) {
System.err.println("Got err " + validation.fail());
}
// check for success
if (validation.isSuccess()) {
System.out.println("All was good :-)");
}
// this will just print out a message if we got no error
validation.forEach(unit -> System.out.println("All was good"));
There is java.lang.AutoCloseable which has a ()->{} throws Exception signature, however, it is burden with a predefined semantic. So for an ad-hoc use it might be suitable but when you design an API, I recommend defining your own interface.
Note that your specialized interface could still extend Callable<Void> to be a standard interface:
interface Block<E extends Exception> extends Callable<Void>{
void run() throws E;
@Override default Void call() throws E { run(); return null; }
/** This little helper method avoids type casts when a Callable is expected */
static <T extends Exception> Block<T> make(Block<T> b) { return b; }
}
This way you can use your Block interface with existing APIs:
// Example
ExecutorService e=Executors.newSingleThreadExecutor();
try {
e.submit(Block.make(()->{ throw new IOException("test"); })).get();
} catch (InterruptedException ex) {
throw new AssertionError(ex);
} catch (ExecutionException ex) {
System.out.println("received \""+ex.getCause().getMessage()+'"');
}
e.shutdown();
Note the trick with the static method Block.make. Without it you would have to cast the lambda expression to (Block<IOException>) instead of profiting from the improved type inference. This is only necessary where a Callable is expected, for your own API where a Block is expected, you can use lambda expressions and method references directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With