当前位置: 首页 > 面试题库 >

为什么我不能在Java 8 lambda表达式中引发异常?

段恩
2023-03-14
问题内容

我升级到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的快速修复建议对我来说并不正确……它只是在throw语句周围加上了一个try-catch块:

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>未在其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 8,并试图用一个新的lamdba表达式替换通过映射的简单迭代。循环搜索空值,如果找到,则抛出异常。旧的Java 7代码如下所示: 我尝试将其转换为Java 8,如下所示: 有人能解释为什么这里不允许语句以及如何纠正这一点吗? Eclipse的快速修复建议在我看来不太对劲......它只是用块包围语句:

  • 奇怪的是,标记为“OK”的行编译得很好,但标记为“Error”的行失败了。它们看起来基本上是一样的。

  • 我正在尝试理解语法。考虑以下程序: 在上面的程序中,模式匹配中使用的编译正常。当我尝试在like我得到编译错误: 我试图理解为什么不能在中使用。

  • 我试图表达10的幂10,但它不起作用,所以我认为问题是数据类型的范围。 我的预期答案是10000000000,但运算结果是1410065408 有什么问题?

  • 问题内容: 我正在阅读有关Java 8的教程,作者在 其中显示了代码: 然后说 无法从lambda表达式内访问默认方法。以下代码无法编译: 但是他没有解释为什么这是不可能的。我运行了代码,但出现了错误, 不兼容的类型:公式不是功能界面` 那么为什么不可能或错误的含义是什么呢? 该接口满足具有一种抽象方法的功能接口的要求。 问题答案: 这或多或少是范围的问题。从JLS 与出现在匿名类声明中的代码不同

  • 问题内容: 我正在尝试使用CASE表达式创建一个持久化的计算列: MSDN明确表示CASE是确定性的,这里 但是,我得到一个错误: 消息4936,级别16,状态1,行1表’Calendar’中的计算列’PreviousDate’无法保留,因为该列是不确定的。 当然,我可以创建一个标量UDF并将其显式声明为确定性的,但是有没有更简单的方法呢?我已经在获取最新的Service Pack中。谢谢。 问题