Lambda中的无限while循环内的Thread.sleep不需要'catch(InterruptedException)'-为什么不呢?

Lambda中的无限while循环内的Thread.sleep不需要'catch(InterruptedException)'-为什么不呢?,第1张

Lambda中的无限while循环内的Thread.sleep不需要'catch(InterruptedException)'-为什么不呢?

这样做的原因是,这些调用实际上是对

ExecutorService
;中可用的两种不同的重载方法的调用。这些方法中的每一个均采用不同类型的单个参数:

  1. <T> Future<T> submit(Callable<T> task);
  2. Future<?> submit(Runnable task);


然后发生的事情是,编译器正在将问题的第一种情况下的lambda转换为

Callable<?>
功能接口(调用第一个重载方法)。在第二个问题中,您将lambda转换为
Runnable
功能接口(因此调用了第二个重载方法),因此需要处理该
Exception
抛出的异常;但在以前的情况下不使用
Callable

尽管两个功能接口均不接受任何参数,但

Callable<?>
返回值

  1. 可致电:
    V call() throws Exception;
  2. 可运行的:
    public abstract void run();


如果我们切换到将代码修整到相关部分的示例(以便轻松地研究好奇的位),那么我们可以编写与原始示例等效的代码:

    ExecutorService executor = Executors.newSingleThreadExecutor();    // LAMBDA COMPILED INTO A 'Callable<?>'    executor.submit(() -> {        while (true) throw new Exception();    });    // LAMBDA COMPILED INTO A 'Runnable': EXCEPTIONS MUST BE HANDLED BY LAMBDA ITSELF!    executor.submit(() -> {        boolean value = true;        while (value) throw new Exception();    });

通过这些示例,可能更容易观察到第一个被转换为a

Callable<?>
,而第二个被转换为a
Runnable
的原因是由于 编译器推断

在这两种情况下,lambda主体都是无效的,因为该块中的每个return语句都具有形式

return;

现在,在第一种情况下,编译器将执行以下 *** 作:

  1. 检测到lambda中的所有执行路径都声明抛出检查过的异常(从现在开始,我们将其称为 “ exception” ,仅表示 “ checked exceptions” )。这包括调用任何声明抛出异常的方法以及对的显式调用
    throw new <CHECKED_EXCEPTION>()
  2. 正确的结论是, WHOLE 拉姆达的身体相当于代码声明抛出异常块; 当然 必须 :处理或重新抛出。
  3. 由于lambda不会处理该异常,因此编译器默认情况下假定必须重新抛出这些异常。
  4. 安全地推断此lambda必须与功能接口匹配
    complete normally
    ,因此是值兼容的。
  5. 由于
    Callable<?>
    Runnable
    是该lambda的潜在匹配项,因此编译器会选择最具体的匹配项(以涵盖所有方案);这是
    Callable<?>
    ,将lambda转换为其实例,并创建对
    submit(Callable<?>)
    重载方法的调用引用。

在第二种情况下,编译器执行以下 *** 作:

  1. 检测lambda中可能存在 声明抛出异常的执行路径(取决于 要评估的逻辑 )。
  2. 由于不是所有的执行路径声明抛出异常,编译器的结论是,拉姆达的身体是 不是必然 等同于代码声明抛出异常块-编译不在乎/注意,如果代码的某些部分做宣布,他们可能,只有整个身体都可以。
  3. 安全地推断出lambda不兼容价值;自 五月 以来
    complete normally
  4. 选择
    Runnable
    (因为它是要转换为lambda 的唯一可用的 拟合 功能接口),并创建对
    submit(Runnable)
    重载方法的调用引用。所有这些都是以委托给用户为代价的,即有责任处理 可能* 在lambda主体部分中发生的任何
    Exception
    地方所引发的所有问题。
    *

这是一个很好的问题-追逐它让我很开心,谢谢!



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5587148.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存