当前位置: 首页 > 知识库问答 >
问题:

Java 8 Lambda函数抛出异常?

穆铭晨
2023-03-14

我知道如何创建对具有string参数并返回int的方法的引用,它是:

Function<String, Integer>

但是,如果函数抛出异常(假设它被定义为:

Integer myMethod(String s) throws IOException

我如何定义这个引用?

共有2个答案

裴心水
2023-03-14

实际上,您可以使用处理异常的新接口扩展consumer(和function等)--使用Java 8的默认方法!

请考虑此接口(extendsconsumer):

@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {

    @Override
    default void accept(final T elem) {
        try {
            acceptThrows(elem);
        } catch (final Exception e) {
            // Implement your own exception handling logic here..
            // For example:
            System.out.println("handling an exception...");
            // Or ...
            throw new RuntimeException(e);
        }
    }

    void acceptThrows(T elem) throws Exception;

}

然后,例如,如果您有一个列表:

final List<String> list = Arrays.asList("A", "B", "C");

如果您想用一些抛出异常的代码来使用它(例如,使用foreach),那么您通常会设置一个try/catch块:

final Consumer<String> consumer = aps -> {
    try {
        // maybe some other code here...
        throw new Exception("asdas");
    } catch (final Exception ex) {
        System.out.println("handling an exception...");
    }
};
list.forEach(consumer);

但是有了这个新接口,您可以用lambda表达式实例化它,编译器就不会抱怨了:

final ThrowingConsumer<String> throwingConsumer = aps -> {
    // maybe some other code here...
    throw new Exception("asdas");
};
list.forEach(throwingConsumer);

或者干脆把它铸得更简洁!:

list.forEach((ThrowingConsumer<String>) aps -> {
    // maybe some other code here...
    throw new Exception("asda");
});

更新:看起来Durian中有一个非常好的实用程序库,叫做Errors,它可以用来解决这个问题,并且具有更大的灵活性。例如,在上面的实现中,我显式定义了错误处理策略(system.out...throw runtimeexception),而Durian的错误允许您通过一大套实用工具方法即时应用策略。谢谢分享,@nedtwigg!

示例用法:

list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
融修平
2023-03-14

您需要执行以下操作之一。

>

  • 如果是您的代码,则定义您自己的函数接口来声明检查的异常:

    @FunctionalInterface
    public interface CheckedFunction<T, R> {
       R apply(T t) throws IOException;
    }
    

    并使用它:

    void foo (CheckedFunction f) { ... }
    

    否则,将integer myMethod(String s)包装在一个不声明检查异常的方法中:

    public Integer myWrappedMethod(String s) {
        try {
            return myMethod(s);
        }
        catch(IOException e) {
            throw new UncheckedIOException(e);
        }
    }
    

    后来呢:

    Function<String, Integer> f = (String t) -> myWrappedMethod(t);
    

    或:

    Function<String, Integer> f =
        (String t) -> {
            try {
               return myMethod(t);
            }
            catch(IOException e) {
                throw new UncheckedIOException(e);
            }
        };
    

  •  类似资料:
    • 我有一个异步函数,我希望在失败时抛出异常。然而,似乎有一些东西阻止了这一点: 通过省略try catch块,我希望抛出一个异常,我想在函数外部处理这个异常。 我得到的实际结果有点令人困惑: 当我尝试捕获异常并抛出其他东西时,会得到相同的结果: 该函数是从try块调用的,因此看不到这如何是未处理的promise。 我正在尝试使用< code>f作为另一个函数的参数:

    • 问题内容: 我知道如何创建对具有参数的方法的引用,并返回,它是: 但是,如果该函数引发异常,例如定义为: 如何定义此参考? 问题答案: 你需要执行以下操作之一。 如果是你的代码,请定义自己的函数接口,该接口声明已检查的异常: 并使用它: 否则,包装一个不声明检查异常的方法: 接着: 要么:

    • 这是主要的方法: 运行时,这是堆栈跟踪:

    • 抛出异常的行为是否可能抛出不同的异常? 为了抛出异常,必须(可选地)分配新对象,并调用其构造函数(隐式调用fillinstacktrace)。在某些情况下,听起来像addSupressed也被称为。那么如果没有足够的内存会发生什么呢?JVM是否需要预分配内置异常?例如,(1/0)会抛出OutOfMemoryError而不是ArithmeticException吗? 此外,构造函数是一个方法调用,因

    • 问题内容: 考虑以下代码: 无需添加方法签名即可编译该代码。(它与同样表现到位,太)。 我理解为什么 可以 安全地运行它,因为实际上不能将其引发在块中,因此不能引发已检查的异常。我有兴趣知道在何处指定此行为。 并非永远都不会达到目标:以下代码也会编译: 但是,如果抛出一个检查的异常,它不会像我期望的那样编译: 在JLS Sec 11.2.2中 ,它说: 一,其抛出的表达式语句(§14.18)具有静

    • 问题内容: 我试图在Netbeans中重构一个大型程序,但我有点迷茫。我从来没有非常模块化,但是现在通过实际学习如何做到这一点来尝试纠正这种情况,并在将来纠正这种情况。不幸的是,我在将某些教程翻译成我的程序时遇到了麻烦。所以我希望这里有人可以帮忙。目前,我正在尝试分解一部分采用特定格式的文件并制成表格的代码。我知道我需要创建一个类并使用它来创建表对象,但是我不确定如何做。我有一个主文件,用于获取文