Java 8:lambda 表达式中的强制检查异常处理。为什么是强制性的,而不是可选的?
我正在使用Java 8中新的lambda特性,发现Java 8提供的实践非常有用。但是,我想知道是否有一种好方法可以为以下方案进行解决。假设您有一个对象池包装器,它需要某种工厂来填充对象池,例如(使用):java.lang.functions.Factory
public class JdbcConnectionPool extends ObjectPool<Connection> {
public ConnectionPool(int maxConnections, String url) {
super(new Factory<Connection>() {
@Override
public Connection make() {
try {
return DriverManager.getConnection(url);
} catch ( SQLException ex ) {
throw new RuntimeException(ex);
}
}
}, maxConnections);
}
}
将函数接口转换为 lambda 表达式后,上面的代码将变为:
public class JdbcConnectionPool extends ObjectPool<Connection> {
public ConnectionPool(int maxConnections, String url) {
super(() -> {
try {
return DriverManager.getConnection(url);
} catch ( SQLException ex ) {
throw new RuntimeException(ex);
}
}, maxConnections);
}
}
确实不是那么糟糕,但是检查的异常需要在lambda内部有一个/块。在我的公司,我们长期使用两个接口:java.sql.SQLException
try
catch
-
IOut<T>
这相当于java.lang.functions.Factory
; - 和一个特殊接口,用于通常需要检查异常传播的情况:.
interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }
在迁移到 Java 8 的过程中,应该会同时删除 这两者,但是 没有完全匹配的 。如果 lambda 表达式可以像未选中一样处理选中的异常,则可以在上面的构造函数中简单地使用如下方式:IOut<T>
IUnsafeOut<T>
IUnsafeOut<T, E>
super(() -> DriverManager.getConnection(url), maxConnections);
这看起来更干净。我看到我可以重写超类来接受我们的,但据我所知,Java 8还没有完成,所以可能会有一些变化,比如:ObjectPool
IUnsafeOut<T>
- 实现类似于 ?(说实话,我认为这是肮脏的 - 主题必须选择接受什么:要么“不安全的工厂”,不能有兼容的方法签名)
IUnsafeOut<T, E>
Factory
- 简单地忽略 lambda 中已检查的异常,因此不需要代理项?(为什么不呢?例如,另一个重要的变化:我使用的OpenJDK现在不需要将变量和参数声明为在匿名类[功能接口]或lambda表达式中捕获)
IUnsafeOut<T, E>
javac
final
所以问题通常是:有没有办法绕过lambdas中经过检查的异常,还是在Java 8最终发布之前计划在将来?
更新 1
Hm-m-m,据我所知,我们目前似乎没有办法,尽管引用的文章可以追溯到2010年:Brian Goetz解释了Java中的异常透明度。如果Java 8中没有太大变化,这可以被认为是一个答案。Brian也说(我提到的超出我们的代码遗产)几乎是无用的,我同意他的观点。interface ExceptionalCallable<V, E extends Exception>
IUnsafeOut<T, E extends Throwable>
我还会错过别的东西吗?