Java 8:在lambda表达式中强制检查异常处理。为什么强制,不是可选的? [英] Java 8: Mandatory checked exceptions handling in lambda expressions. Why mandatory, not optional?
问题描述
我正在使用Java 8中的新lambda特性,并发现Java 8提供的实践非常有用。但是,我想知道是否有一种良好的方法可以解决以下情况。假设您有一个对象池包装器,需要某种工厂来填充对象池,例如(使用 java.lang.functions.Factory
):
I'm playing with the new lambda features in Java 8, and found that the practices offered by Java 8 are really useful. However, I'm wondering is there a good way to make a work-around for the following scenario. Suppose you have an object pool wrapper that requires some kind of a factory to fill the object pool, for example (using 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后表达式,上面的代码变成这样:
After transforming the functional interface into lambda expression, the code above becomes like that:
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
需要尝试
/ catch
阻挡lambda内部。在我公司,我们长时间使用两个接口:
Not so bad indeed, but the checked exception java.sql.SQLException
requires a try
/catch
block inside the lambda. At my company we use two interfaces for long time:
-
IOut< T>
这相当于java.lang.functions.Factory
; - 以及通常需要检查异常传播的案例的特殊接口:
interface IUnsafeOut< T,E extends Throwable> {T out()抛出E; }
。
IOut<T>
that is an equivalent tojava.lang.functions.Factory
;- and a special interface for the cases that usually require checked exceptions propagation:
interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }
.
两者 IOut< T>
在迁移到Java 8期间应该删除 IUnsafeOut< T>
,但是 IUnsafeOut< T,E>
。如果lambda表达式可以处理未经检查的已检查异常,则可以像上面的构造函数中的以下内容一样使用:
Both IOut<T>
and IUnsafeOut<T>
are supposed to be removed during migration to Java 8, however there is no exact match for IUnsafeOut<T, E>
. If the lambda expressions could deal with checked exceptions like they were unchecked, it could be possible to use simply like the following in the constructor above:
super(() -> DriverManager.getConnection(url), maxConnections);
看起来更干净。我看到我可以重写 ObjectPool
超类来接受我们的 IUnsafeOut< T>
,但据我所知,Java 8还没有完成,所以可能会有一些变化,如:
That looks much cleaner. I see that I can rewrite the ObjectPool
super class to accept our IUnsafeOut<T>
, but as far as I know, Java 8 is not finished yet, so could be there some changes like:
- 实现与
类似的东西IUnsafeOut< T,E>
? (老实说,我认为这很脏 - 主题必须选择接受:工厂
或不安全的工厂,不能有兼容的方法签名) - 只是忽略lambdas中的已检查异常,因此不需要
IUnsafeOut< T,E>
代理人? (为什么不呢?例如,另一个重要的变化:我使用的OpenJDK,javac
现在不需要将变量和参数声明为final
要在匿名类[功能接口]或lambda表达式中捕获)
- implementing something similar to
IUnsafeOut<T, E>
? (to be honest, I consider that dirty - the subject must choose what to accept: eitherFactory
or "unsafe factory" that cannot have compatible method signatures) - simply ignoring checked exceptions in lambdas, so no need in
IUnsafeOut<T, E>
surrogates? (why not? e.g. another important change: OpenJDK, that I use,javac
now does not require variables and parameters to be declared asfinal
to be captured in an anonymous class [functional interface] or lambda expression)
所以问题通常是:是有没有办法绕过lambdas中的已检查异常,或者计划将来直到Java 8最终发布?
So the question is generally is: is there a way to bypass checked exceptions in lambdas or is it planned in the future until Java 8 is finally released?
更新1
嗯-mm,据我所知,我们目前的情况看来,目前似乎没有办法,尽管参考文章的日期是2010年:< A HREF = https://web.archive.org/web/20170313093438/blogs.oracle.com/briangoetz/entry/exception_transparency_in_java 相对= nofollow noreferrer>作者Brian Goetz解释了Java的异常的透明度。如果在Java 8中没有什么变化,这可以被认为是一个答案。也布赖恩说接口ExceptionalCallable< V,E延伸异常>
(我提到 IUnsafeOut< T,E延伸的Throwable>
我们的代码遗产)几乎没用,我同意他的意见。
Hm-m-m, as far as I understand what we currently have, it seems there is no way at the moment, despite the referenced article is dated from 2010: Brian Goetz explains exception transparency in Java. If nothing changed much in Java 8, this could be considered an answer. Also Brian says that interface ExceptionalCallable<V, E extends Exception>
(what I mentioned as IUnsafeOut<T, E extends Throwable>
out of our code legacy) is pretty much useless, and I agree with him.
我还有其他的东西吗?
推荐答案
不确定我是否真的回答了你的问题,但你不能简单地使用类似的东西吗?
Not sure I really answer your question, but couldn't you simply use something like that?
public final class SupplierUtils {
private SupplierUtils() {
}
public static <T> Supplier<T> wrap(Callable<T> callable) {
return () -> {
try {
return callable.call();
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
};
}
}
public class JdbcConnectionPool extends ObjectPool<Connection> {
public JdbcConnectionPool(int maxConnections, String url) {
super(SupplierUtils.wrap(() -> DriverManager.getConnection(url)), maxConnections);
}
}
这篇关于Java 8:在lambda表达式中强制检查异常处理。为什么强制,不是可选的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!