Java 8中使用Lambda表达式进行异常处理

3
我正在使用lambda表达式进行一些测试,但我的代码无法编译。我的lambda实现有问题还是异常处理有误?以下代码的正确实现方式应该是什么?
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();

如果我移除try catch块并在方法中声明要抛出的异常,代码将编译并正常运行。

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

编译错误是:
不兼容类型:lambda表达式中的返回类型错误

2
这实际上与lambda没有太多关系。如果您以正常方式声明它,相同的方法体将无法编译。错误消息并不特别有信息性。 - Radiodef
3个回答

6
你的lambda需要返回一个MyObject对象。如果try块成功完成,那么就会返回该对象,但如果没有成功,则会执行catch块,该块不会返回任何内容。因此,你可以这样写:
```python try: # some code here return MyObject() except: # handle exception here ```
Creatable<MyObject> creator = () ->  {
    try {
        return new MyObject();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
};

但是你会得到另一个编译错误:"在try块中永远不会抛出IOException"。因此,你还需要在MyObject中拥有一个抛出IOException的构造函数:

class MyObject { MyObject() throws IOException {} }

最终,除非MyObject实际抛出异常,否则您可以简单地使用以下代码:
Creatable<MyObject> creator = () -> new MyObject();

你也可以写成:

Creatable<MyObject> creator = MyObject::new;

即使new MyObject()抛出异常,你也可以这样写。无论如何,该接口的使用者必须准备好从中获得IOException。这正是以这种方式实现接口的目的所在。 - glglgl

1
Lambda需要所有路径返回值,就像前面的答案所提到的那样,简单的解决方案是在catch块的末尾返回值。
然而,在使用lambda时,有一种更优雅的处理异常的方法。
您可以用另一个lambda包装它。例如: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


0
@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);
        }
    };
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接