因此,我试图重构以下代码:
/**
* 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);
}首先,我想出了以下几点:
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的方法声明中?
还是像下面这样做的唯一方法?
@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的最初原因是为了颠倒基本功能,例如默认方法。
发布于 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));
发布于 2014-03-27 12:46:31
Supplier使用,因为它只会抛出UnsupportedOperationException。getWithIO方法呢?
@FunctionalInterface公共接口SupplierWithIO { public T getWithIO()抛出IOException;}发布于 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倍的爆炸(例外和非),这与现有的用于原始专门化的组合爆炸发生了严重的交互。 可用的基于语言的解决方案是复杂性/价值权衡的输家。虽然有一些替代的解决方案,我们将继续探索 同时,你有工具去做你想做的事。我知道你更希望我们为你提供最后一英里(其次,你的请求实际上是一个隐晦的请求,“你为什么不放弃检查过的异常”),但我认为当前的状态可以让你完成你的工作。
https://stackoverflow.com/questions/22687943
复制相似问题