我正在尝试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
块。在我的公司,我们长期使用两个接口:
相当于java.lang.functions.Factory
;
IOut<T>
,一个特殊的接口,用于通常需要检查异常传播的情况:interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }
.在迁移到Java8的过程中,IOut<T>
和IUnsafeOut<T>
都应该被删除,但是没有与IUnsafeOut<T, E>
完全匹配的版本。如果lambda表达式可以像处理未检查的异常一样处理已检查的异常,则可以在上面的构造函数中简单地使用如下代码:
super(() -> DriverManager.getConnection(url), maxConnections);
看起来干净多了。我看到我可以重写ObjectPool
超类来接受我们的IUnsafeOut<T>
,但据我所知,Java8还没有完成,所以可能会有一些变化,比如:
IUnsafeOut<T, E>
的东西?(老实说,我认为这很脏--主体必须选择接受什么:要么是Factory
,要么是“不安全的工厂”,不能让兼容的方法signatures)IUnsafeOut<T, E>
代理中没有必要吗?(有何不可?例如,另一个重要的变化:我使用的OpenJDK,javac
现在不需要将变量和参数声明为final
,以便在匿名类函数接口或λ表达式中捕获)因此,通常的问题是:有没有办法绕过lambdas中的检查异常,还是计划在Java 8最终发布之前在未来进行?
更新1
嗯-m-m,据我所知,目前似乎没有办法,尽管引用的文章日期是2010年:Brian Goetz explains exception transparency in Java。如果Java 8没有太大的变化,这可以被认为是一个答案。布莱恩还说,interface ExceptionalCallable<V, E extends Exception>
(我在我们的代码遗产中提到的IUnsafeOut<T, E extends Throwable>
)几乎没有用,我同意他的观点。
我还错过了什么吗?
https://stackoverflow.com/questions/14039995
复制相似问题