首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以声明Supplier<T>需要抛出异常?

是否可以声明Supplier<T>需要抛出异常?
EN

Stack Overflow用户
提问于 2014-03-27 12:40:27
回答 6查看 42.8K关注 0票数 42

因此,我试图重构以下代码:

代码语言:javascript
复制
/**
 * Returns the duration from the config file.
 * 
 * @return  The duration.
 */
private Duration durationFromConfig() {
    try {
        return durationFromConfigInner();
    } catch (IOException ex) {
        throw new IllegalStateException("The config file (\"" + configFile + "\") has not been found.");
    }
}

/**
 * Returns the duration from the config file.
 * 
 * Searches the log file for the first line indicating the config entry for this instance.
 * 
 * @return  The duration.
 * @throws FileNotFoundException If the config file has not been found.
 */
private Duration durationFromConfigInner() throws IOException {
    String entryKey = subClass.getSimpleName();
    configLastModified = Files.getLastModifiedTime(configFile);
    String entryValue = ConfigFileUtils.readFileEntry(configFile, entryKey);
    return Duration.of(entryValue);
}

首先,我想出了以下几点:

代码语言:javascript
复制
private <T> T getFromConfig(final Supplier<T> supplier) {
    try {
        return supplier.get();
    } catch (IOException ex) {
        throw new IllegalStateException("The config file (\"" + configFile + "\") has not been found.");
    }
}

但是,它不编译(显然),因为Supplier不能抛出一个IOException。我是否可以将它添加到getFromConfig的方法声明中?

还是像下面这样做的唯一方法?

代码语言:javascript
复制
@FunctionalInterface
public interface SupplierWithIO<T> extends Supplier<T> {
    @Override
    @Deprecated
    default public T get() {
        throw new UnsupportedOperationException();
    }

    public T getWithIO() throws IOException;
}

Update,我刚刚意识到Supplier接口是一个真正的简单接口,因为它只有get()方法。我扩展Supplier的最初原因是为了颠倒基本功能,例如默认方法。

EN

回答 6

Stack Overflow用户

发布于 2017-11-23 15:21:49

编辑

正如多次指出的,您不需要任何自定义类,而是使用可调用Runnable

错误,过时的解决方案

考虑一下这个通用解决方案: //我们需要描述可以抛出异常@FunctionalInterface公共接口ThrowingSupplier {T get()抛出异常的供应商;}/现在,包装私有T callMethod(ThrowingSupplier供应者){尝试{返回supplier.get();} catch (异常e) {抛出新RuntimeException(e);}返回null;} //和使用示例字符串methodThrowsException(字符串a、字符串b、字符串c)抛出异常{ // do } String result = callMethod(() -> methodThrowsException(x,y,z));

票数 22
EN

Stack Overflow用户

发布于 2014-03-27 12:46:31

  • 如果要这样做,就不能将它作为Supplier使用,因为它只会抛出UnsupportedOperationException。
  • 考虑到上述情况,为什么不创建一个新的接口并在其中声明getWithIO方法呢? @FunctionalInterface公共接口SupplierWithIO { public T getWithIO()抛出IOException;}
  • 也许有些东西更适合作为旧风格的Java接口呢?旧风格的Java已经消失,不仅仅是因为现在有了Java 8。
票数 21
EN

Stack Overflow用户

发布于 2014-03-27 13:46:11

在lambda邮件列表中,这是畅谈。正如您所看到的,Brian在这里建议,另一种选择是编写自己的combinator:

或者您也可以编写自己的琐碎组合器: 静态块exceptionWrappingBlock(块b) {返回e -> {尝试{ b.accept( e);}捕捉(异常e){抛出新的b.accept(E);} };} 你可以写一次它,在较少的时间来写你的原始电子邮件。同样地,对于你使用的每一种SAM,也是一次。 我宁愿我们把它看作是“玻璃99%满”,而不是其他的选择。并不是所有的问题都需要新的语言特性作为解决方案。(更不用说新的语言特性总是会带来新的问题。)

在那些日子里,消费者界面被称为Block。

我认为这与上面Marko建议的JB Nizet的回答是一致的。

后来Brian 解释为什么就这样设计了(问题的原因)

是的,你必须提供你自己的特殊导弹。但那样的话,兰巴达的转换就会对他们很好了。 EG讨论了对这个问题的额外语言和库支持,并最终认为这是一种糟糕的成本/效益权衡。 基于库的解决方案在SAM类型中造成2倍的爆炸(例外和非),这与现有的用于原始专门化的组合爆炸发生了严重的交互。 可用的基于语言的解决方案是复杂性/价值权衡的输家。虽然有一些替代的解决方案,我们将继续探索 同时,你有工具去做你想做的事。我知道你更希望我们为你提供最后一英里(其次,你的请求实际上是一个隐晦的请求,“你为什么不放弃检查过的异常”),但我认为当前的状态可以让你完成你的工作。

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22687943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档