java - 为什么我不能在 Java 8 lambda 表达式中抛出异常?

标签 java exception lambda java-8

我升级到 Java 8 并尝试用新的 lamdba 表达式替换通过 Map 进行的简单迭代。循环搜索空值,如果找到则抛出异常。旧的 Java 7 代码如下所示:

for (Map.Entry<String, String> entry : myMap.entrySet()) {
    if(entry.getValue() == null) {
        throw new MyException("Key '" + entry.getKey() + "' not found!");
    }
}

我尝试将其转换为 Java 8 如下所示:

myMap.forEach((k,v) -> {
    if(v == null) {
        // OK
        System.out.println("Key '" + k+ "' not found!");

        // NOK! Unhandled exception type!
        throw new MyException("Key '" + k + "' not found!");
    }
});

谁能解释为什么这里不允许使用 throw 语句以及如何纠正这种情况?

Eclipse 的快速修复建议对我来说不合适...它只是用 try-catch block 围绕 throw 语句:

myMap.forEach((k,v) -> {
    if(v == null) {
        try {
            throw new MyException("Key '" + k + "' not found!");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
});

最佳答案

您不能抛出已检查的异常,因为 accept(T t, U u) java.util.function.BiConsumer<T, U> 中的方法接口(interface)未在其throws 中声明任何异常条款。而且,如您所知, Map#forEach 就是这样的类型。

public interface Map<K, V> {

    default void forEach(BiConsumer<? super K, ? super V> action) { ... }

}                        |
                         |
                         V
@FunctionalInterface
public interface BiConsumer<T, U> {

    void accept(T t, U u); // <-- does throw nothing

}

当我们谈论受检异常时确实如此。但是您仍然可以抛出未经检查的异常(例如 java.lang.IllegalArgumentException ):

new HashMap<String, String>()
    .forEach((a, b) -> { throw new IllegalArgumentException(); });

关于java - 为什么我不能在 Java 8 lambda 表达式中抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37726874/

相关文章:

java - 为什么这里不能使用 throws Exception 呢?

c# - 绑定(bind)函数(委托(delegate))参数

java - Java或C#中工厂设计模式的反射(reflection)

java - 在 spring 应用程序中注入(inject) 2(不久的将来 3)个不同的 entityManagerFactory(或 entityManager)

java - 为什么maven编译失败?

c# - C#中随机抛出的IO异常

c# - Newtonsoft.JSON.dll 中的 StackOverflowException

c# - Func<T> 作为类成员,访问实例的其他成员

python - map() lambda() 操作数仅在 python 2.7.6 中不受支持

java - containarized shinyproxy 非常慢