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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.