Andrey
Andrey

Reputation: 2585

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

Upvotes: 3

Views: 7909

Answers (3)

Sandeep Kumar
Sandeep Kumar

Reputation: 70

@FunctionalInterface
public interface CreateThrowable<T, R, E extends Throwable> {
   R create(T t) throws E;
static <T, R, E extends Throwable> Function<T, R> uncheckedException(ThrowingFunction<T, R, E> f) {
    return t -> {
        try {
            return f.create(t);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    };
}

}

Upvotes: 0

Malik Firose
Malik Firose

Reputation: 389

Lambda needs all paths to return the value as mentioned in the previous answer the easy solution is to return at the end of the catch block

However there is a more elegant way to handle exception when using lambda

you can wrap a lambda with another Example wrap(((x,y)->x/y))

Biconsumer<Integer,Integer> consumer wrap(Biconsumer<Integer,Integer> consumer)    
{    
return (v,k)->{try

{consumer.apply()}

catch(){};

}

https://www.youtube.com/watch?v=YLKMCPMLv60&list=PLqq-6Pq4lTTa9YGfyhyW2CqdtW9RtY-I3&index=18

Upvotes: 1

assylias
assylias

Reputation: 328598

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;

Upvotes: 6

Related Questions