Wrap Lambda expression for Runnable to handle exceptions

TomFT :

I am trying to initialize an array of Runnables and then run their code. I need the initialization be as readable as possible and therefore I am using a Lambda expression for that. Now I don't know how to solve the problem with exceptions. If some code inside of the Runnables throws checked exception I would like to wrap it automatically into a RuntimeException but without putting the try/catch logic into every Runnable body.

The code looks like this:

public void addRunnable(Runnable ... x); // adds a number of Runnables into an array
...
addRunnable(
   ()->{
       some code;
       callMethodThrowsException();  // this throws e.g. IOException
   },

   ()->{
       other code;
   }
   // ... and possibly more Runnables here
);

public void RunnableCaller(List<Runnable> runnables) {
    // Now I want to execute the Runnables added to the array above
    // The array gets passed as the input argument "runnables" here
    for(Runnable x: runnables) {
        try {
            x.run();
        } catch(Exception e) { do some exception handling }
    }
}

The code does not compile because callMethodThrowsException throws a checked exception and Runnable does not so I would have to insert a try/catch block INSIDE of the Runnable definition. The try/catch block would make that thing much less convenient since I would have to put it into each Runnable body declaration which would be hard to read and unpleasant to write. Also I could create my own Runnable class that throws exception but then I cannot use the Lambda expression ()-> which makes it short and readable instead of doing

new ThrowingRunnable() { public void run() throws Exception { some code; } }

Is there a way how to define my own functional interface that would solve this issue so that I can use the same code but exceptions will be wrapped into e.g. RuntimeExceptions or so? I have a full control about the calling code so it is no problem catching the exceptions there, I only need a very readable way of writing code that will be executed later.

I saw this topic Java 8 Lambda function that throws exception? but I did not figure out how to solve my problem from that, I am not very familiar with functional interfaces. May be someone could help, thanks.

Lino :

Lambdas are not only for interfaces provided by the JVM. They can be used for every interface that exactly defines one and only one abstract method. So you can yourself create an interface, you named it already:

public interface ThrowingRunnable{
    void run() throws Exception;
}

And then replace the Parameter type in the addRunnable method:

public void addRunnable(ThrowingRunnable... runnables){ ... }

Which then lets this compile:

addRunnable(
   ()->{
       some code;
       callMethodThrowsException();  // this throws e.g. IOException
   },

   ()->{
       other code;
   }
   // ... and possibly more Runnables here
);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=108185&siteId=1