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
需要在 lambda 中使用 try
/catch
块.在我公司,我们长期使用两个接口:
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
相当于java.lang.functions.Factory
;- 以及通常需要检查异常传播的情况的特殊接口:
interface IUnsafeOut
.{ 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
和 IUnsafeOut
都应该在迁移到 Java 8 期间被删除,但是 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
,但据我所知,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
的东西?(老实说,我认为这很脏 - 主题必须选择接受什么:Factory
或不能具有兼容方法签名的不安全工厂") - 简单地忽略 lambdas 中的检查异常,所以不需要
IUnsafeOut
代理?(为什么不呢?例如另一个重要变化:我使用的 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
嗯,据我所知,目前似乎没有办法,尽管引用的文章是 2010 年的:Brian Goetz 解释了 Java 中的异常透明性.如果 Java 8 中没有发生太大变化,这可以被视为一个答案.布赖恩还说,interface ExceptionalCallable
(我在我们的遗留代码中提到的 IUnsafeOut
)几乎没用,我同意他的看法.
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屋!