Java 8:lambda 表达式中的强制检查异常处理.为什么是强制性的,而不是可选的? [英] Java 8: Mandatory checked exceptions handling in lambda expressions. Why mandatory, not optional?

查看:12
本文介绍了Java 8:lambda 表达式中的强制检查异常处理.为什么是强制性的,而不是可选的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试 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 to java.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; }.

IOutIUnsafeOut 都应该在迁移到 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: either Factory 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 as final 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆