Reputation: 2585
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
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
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
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