Your code fails to wrap the checked exception into an unchecked one. Further, it doesn’t following the hint to use a lambda expression. A corrected version would be:
public static Runnable uncheck(RunnableEx r) { return () -> { try { r.run(); } catch (Exception e) { throw new RuntimeException(e); } }; }
There are indeed possibilities to improve this further. Since the whole purpose of the RunnableEx interface is to wrap a Runnable, you could place the factory method inside the interface itself:
public interface RunnableEx { void run() throws Exception; public static Runnable uncheck(RunnableEx r) { return () -> { try { r.run(); } catch (Exception e) { throw new RuntimeException(e); } }; } }
Of course, now your calling code has to be adapted to:
public static void main(String[] args) { new Thread(RunnableEx.uncheck( () -> { System.out.println("Zzz"); Thread.sleep(1000); } )).start(); }
Now, the interface itself could implement the wrapping feature, becoming compatible with Runnable, which would eliminate the need to have a Runnable and a RunnableEx instance to represent a single action:
public interface RunnableEx extends Runnable { void runWithException() throws Exception; @Override default void run() { try { runWithException(); } catch (Exception e) { throw new RuntimeException(e); } } public static Runnable uncheck(RunnableEx r) { return r; } }
Note that while the calling code doesn’t change syntactically, it will implicitly create a Runnable instance in the first place, when creating the RunnableEx instance, that’s why uncheck becomes a no-op, merely serving as a marker that a RunnableEx should be created rather than a Runnable. With this interface definition, you could achieve the same via
public static void main(String[] args) { new Thread( (RunnableEx) () -> { System.out.println("Zzz"); Thread.sleep(1000); } ).start(); }
The reason why you can’t “just use” a Callable<Void> here, is that Callable<Void> still is a Callable, requiring the implementation code to return a value. In other words, there is no implicit conversion from void to Void. So you can use it, but the lambda expression would require a return null; statement at its end then (null is the only value compatible with Void).
public class TestUncheck { public static Runnable uncheck(Callable<Void> r) { return () -> { try { r.call(); } catch (Exception e) { throw new RuntimeException(e); } }; } public static void main(String[] args) { new Thread(uncheck( () -> { System.out.println("Zzz"); Thread.sleep(1000); return null; } )).start(); } }