Is there a standard Java 8 FunctionalInterface for a block throwing a checked exception?

Throwing Exception, Runnable not working.

Is there anything standard that looks like

@FunctionalInterface
public interface TypedBlock<E extends Exception> {
    public void run() throws E;
}

      

+3


source to share


2 answers


No, there are no built-in functions as I know. But you can use an external library for this (and many other cool features).

You can use JOOL where you can use Unchecked to do this.

The example from this page demonstrates this with 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 functionally designed library like Functionaljava .

A good approach would be to turn your problem into Validation

, and then decide if the result was successful. It might 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"));

      

+3


source


There is java.lang.AutoCloseable

one that has a signature ()->{} throws Exception

, however this is due to predefined semantics. So for ad-hoc use it might be handy, but when you're developing an API, I recommend defining your own interface

.

Note that your custom interface can still extend Callable<Void>

as 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();

      

Notice the static method trick Block.make

. Without it, you would need to express the lambda expression on (Block<IOException>)

instead of taking advantage of improved type inference. This is only needed where expected Callable

, for your own API, where expected Block

, you can use lambda expressions and method references directly.

+2


source







All Articles