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

查看:190
本文介绍了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 需要尝试 / 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 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; }.

两者 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: 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

嗯-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屋!

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