我正在使用 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);
}
}
确实没那么糟糕,但是检查的异常java.sql.SQLException
需要lambda 内的try
/块。catch
在我公司,我们长期使用两个接口:
IOut<T>
相当于java.lang.functions.Factory
;- 以及通常需要检查异常传播的情况的特殊接口:
interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }
.
两者IOut<T>
和IUnsafeOut<T>
都应该在迁移到 Java 8 期间被删除,但是没有完全匹配的IUnsafeOut<T, E>
. 如果 lambda 表达式可以像未检查一样处理已检查的异常,则可以在上面的构造函数中像下面这样简单地使用:
super(() -> DriverManager.getConnection(url), maxConnections);
这样看起来干净多了。我看到我可以重写ObjectPool
超类来接受我们的IUnsafeOut<T>
,但据我所知,Java 8 还没有完成,所以可能会有一些变化,比如:
- 实现类似的东西
IUnsafeOut<T, E>
?(老实说,我认为这很脏 - 主题必须选择接受什么:要么Factory
或不能具有兼容方法签名的“不安全工厂”) - 只是忽略 lambdas 中的检查异常,所以不需要
IUnsafeOut<T, E>
代理?(为什么不呢?例如另一个重要的变化:我使用的 OpenJDKjavac
现在不需要将变量和参数声明为final
在匿名类 [功能接口] 或 lambda 表达式中捕获)
所以问题通常是:有没有办法绕过 lambdas 中的已检查异常,还是在 Java 8 最终发布之前计划在将来?
更新 1
嗯,据我了解我们目前所拥有的,目前似乎没有办法,尽管引用的文章是 2010 年的:Brian Goetz 解释 Java 中的异常透明度。如果在 Java 8 中没有发生太大变化,这可以被视为一个答案。Brian 还说interface ExceptionalCallable<V, E extends Exception>
(我提到IUnsafeOut<T, E extends Throwable>
的代码遗留问题)几乎没有用,我同意他的观点。
我还想念别的东西吗?