【问题标题】:Method signature including the throws exception?包括抛出异常的方法签名?
【发布时间】:2018-05-21 12:07:51
【问题描述】:

我知道方法签名包括方法名称及其参数列表

那么throws Exception呢?

public List<ServiceStatusVo> listServiceStatuses() throws RetrieverException {
    ...
    return list;
}

如果不包含,那么为什么我不能传入以下 lambda:

() -> listServiceStatuses()

但我可以进去

() -> {
    try {
        return listServiceStatuses();
    } catch (RetrieverException e) {
    }
}

而且我也可以把它扔掉再次

() -> {
    try {
        return listServiceStatuses();
    } catch (RetrieverException e) {
        throw e;
    }
}

我知道Supplier&lt;T&gt; 功能接口,这让我真正感到困惑如果 抛出 不是方法签名 的一部分。

感谢您的帮助。

【问题讨论】:

  • 好像您已经回答了自己的问题,不是吗? Supplier.get() 不会抛出任何已检查异常,因此抛出已检查异常的 lambda 将不符合所需的类型。
  • @jspcal 我只是有这种感觉,但直到现在我还没有找到任何官方文档来指定它。你能提供一些细节吗?
  • @VictorGubin 我知道那篇描述如何处理这种情况的帖子,但我想知道的是为什么
  • @VictorGubin 不是真的,没有什么可以阻止 lambda 抛出检查异常(例如interface CheckedSupplier&lt;T, E&gt; { T get() throws E; });你不能把它扔给Supplier 类型。

标签: java lambda java-8 functional-interface throws


【解决方案1】:

这与方法签名无关。来自JLS Sec 11.2.3

当 E 是 已检查异常并且 E 不是 子类时,如果 lambda 主体可以抛出一些异常类 E,则这是一个编译时错误 在 lambda 表达式所针对的函数类型的 throws 子句中声明的某个类。

这有点令人惊讶——我必须承认我最初的想法是异常方法签名的一部分。

但请记住,“已检查异常”是指compile-time checked exception:编译器确保您已处理所有已检查异常;但是一旦它被编译,检查和未检查的异常类型就会被同等对待。请注意,the JVM spec 在异常部分中甚至没有提到检查性。

因此,正如在运行时所见,该方法可以抛出任何异常。正如语言规范中所述:

如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为M的类型参数,形式参数类型相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多