Search code examples
javalambdajava-8functional-interface

Exception handling using Lambda in Java 8


I'm doing some tests using lambda expressions but my code does not compile. My lambda implementation is wrong or the exception handling? What would be the correct implementation of the following code?

class MyObject { }

interface Creatable<T> {
    T create() throws IOException;
}

/* Using the code: */
Creatable<MyObject> creator = () ->  {
    try {
        return new MyObject();
    } catch (IOException e) {
        e.printStackTrace();
    }
};

MyObject obj1 = creator.create();

If i remove the try catch block and declare the exception to throw in the method, the code compiles and runs normally.

Creatable<MyObject> creator = () -> new MyObject();

The compilation error is:

incompatible types: bad return type in lambda expression


Solution

  • Your lambda needs to return a MyObject. If the try block completes successfully that is the case, but if it doesn't the catch block is executed which does not return anything. So you could write:

    Creatable<MyObject> creator = () ->  {
        try {
            return new MyObject();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    };
    

    But then you will get another compile error: "IOException is never thrown in try block". So you would also need to have a constructor in MyObject that throws an IOException:

    class MyObject { MyObject() throws IOException {} }
    

    In the end, unless MyObject actually throws an exception, you can simply use:

    Creatable<MyObject> creator = () -> new MyObject();
    

    which you can also write:

    Creatable<MyObject> creator = MyObject::new;