gpt4 book ai didi

Java 8 : Mandatory checked exceptions handling in lambda expressions. 为什么是强制性的,而不是可选的?

转载 作者:IT老高 更新时间:2023-10-28 13:51:25 27 4
gpt4 key购买 nike

我正在使用 Java 8 中的新 lambda 功能,发现 Java 8 提供的实践非常有用。但是,我想知道是否有一种 good 方法可以解决以下情况。假设您有一个对象池包装器,它需要某种工厂来填充对象池,例如(使用 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);
}

}

函数式接口(interface)转换成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需要 try/catch在 lambda 内阻塞。在我公司,我们长期使用两个接口(interface):

  • IOut<T>相当于java.lang.functions.Factory ;
  • 以及用于通常需要检查异常传播的情况的特殊接口(interface):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 或不能具有兼容方法签名的“不安全工厂”)
  • 只需忽略 lambda 中的已检查异常,因此 IUnsafeOut<T, E> 中不需要代理人? (为什么不呢?例如,另一个重要的变化:我使用的 OpenJDK javac 现在不需要将变量和参数声明为 final 以在匿名类 [功能接口(interface)] 或 lambda 表达式中捕获)

所以问题通常是:有没有办法绕过 lambdas 中的已检查异常,还是在 Java 8 最终发布之前计划在将来?


更新 1

嗯,嗯,据我了解,目前似乎没有办法,尽管引用的文章是从 2010 年开始的:Brian Goetz explains exception transparency in Java .如果在 Java 8 中没有发生太大变化,这可以被视为一个答案。布赖恩还说interface ExceptionalCallable<V, E extends Exception> (我在代码遗留中提到的 IUnsafeOut<T, E extends Throwable> 几乎没有用,我同意他的观点。

我还有什么想念的吗?

最佳答案

不确定我是否真的回答了你的问题,但你不能简单地使用类似的东西吗?

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 : Mandatory checked exceptions handling in lambda expressions. 为什么是强制性的,而不是可选的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14039995/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com