【问题标题】:what's the differences between Supplier<X> and Supplier<? extends X>供应商<X> 和供应商< 之间有什么区别?扩展 X>
【发布时间】:2021-07-15 10:07:08
【问题描述】:

在“可选”源代码中,我找到了这个函数:

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

我的问题是,如果我将功能更改为这个,它看起来就像工作一样

public <X extends Throwable> T orElseThrow(Supplier<X> exceptionSupplier) throws X {
    if (value != null) {
        return value;
    } else {
        throw exceptionSupplier.get();
    }
}

有人知道原因吗?

【问题讨论】:

  • 嗯,有区别。您的建议将无法采用Supplier&lt;ChildException&gt;,它会在其签名中包含ChildException 时抛出throws ParentException

标签: java wildcard optional supplier


【解决方案1】:

考虑这种方法:

void example() throws IOException {
  throw new FileNotFoundException();
}

这声明它抛出一般的IOException,但具体抛出一个更具体的异常FileNotFoundException

orElseThrow 相同:通过接受上限供应商,它可以抛出更具体的异常类型。

在大多数情况下,差异是无关紧要的,因为您总是可以捕获/throws 更通用的异常类型。我认为可能会有所不同的情况是,当您接受 Supplier 作为参数时:

<X extends IOException> void example(Supplier<? extends X> exceptionSupplier)
    throws IOException {  // Note IOException, not X.
  Optional.empty().orElseThrow(exceptionSupplier);
}

您可以使用以下任一供应商作为参数调用它:

Supplier<IOException> s1 = IOException::new;
Supplier<FileNotFoundIOException> s2 = FileNotFoundIOException::new;

但如果没有Supplier&lt;? extends X&gt; 的上限,您将无法执行后者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 2015-03-15
    • 2010-12-23
    • 2019-02-18
    • 1970-01-01
    • 2019-06-17
    • 2017-05-05
    相关资源
    最近更新 更多