这些结构之间的区别是什么,一个不会编译? [英] What is the difference between these constructs such that one won't compile?

查看:119
本文介绍了这些结构之间的区别是什么,一个不会编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有点背景故事(确定,很多):我一直在努力创建类 java.util.function 类型,用 try / catch 块包装它们的执行,以消除在lambda语句中使用 try / catch 的需要。允许此测试代码的任何东西:

A little backstory (ok, a lot): I've been working on creating classes that take java.util.function types and wrap their execution with try/catch blocks to remove the need for using try/catch from within lambda statements. Something that would allow this test code:

list.forEach(ExceptionWrapper.wrapConsumer(s -> {throw new Exception(s);}));

在这样做的时候,我想出了这个。 不起作用。

In doing so, I came up with this. It did not work.

public class ExceptionWrapper {
    public static <T> Consumer<T> wrapConsumer(Consumer<T> consumer){
        return t -> {
            try {
                consumer.accept(t);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        };
    }
}

许多咒语总会导致

Error:(54, 61) java: unreported exception java.lang.Exception; must be caught or declared to be thrown

经过大量搜索,我遇到了jOOλ code。它看起来几乎相同,除了他们使用一个中间lambda构造,模仿包装类型,但声明抛出异常。我做了我自己的( 复制代码,只是概念),它工作非常真棒

After much searching, I came across the jOOλ code. It looked nearly the same except they use an intermediary lambda construct that mimics the wrapped types but declares to throw an exception. I made my own (did NOT copy the code, just the concept) and it works pretty awesome

public interface ConsumerWrapper<T>{
    void accept(T t) throws Exception;
}

并将更改 ExceptionWrapper

    public static <T> Consumer<T> wrapConsumer(ConsumerWrapper<T> consumer){
        ...                                        //  ^ note change
    }

允许初始测试代码编译和运行。

allows the initial test code to compile and run.

public static void main(String[] args) {
    List<String> strings = Arrays.asList("1");
    strings.forEach(System.out::println);
    strings.forEach(ExceptionWrapper.wrapConsumer(s -> {throw new Exception(s);}));
}



Exception in thread "main" java.lang.RuntimeException: java.lang.Exception: 1
    at crap.unk.ExceptionWrapper.lambda$wrapConsumer$2(ExceptionWrapper.java:39)
    at crap.unk.ExceptionWrapper$$Lambda$3/1401420256.accept(Unknown Source)
...
Caused by: java.lang.Exception: 1
    at crap.unk.ExceptionWrapper.lambda$main$3(ExceptionWrapper.java:54)
    at crap.unk.ExceptionWrapper$$Lambda$2/501263526.accept(Unknown Source)

问题

?为什么使用中间体,具有相同的结构,使其工作?这似乎是由 throws 子句的差异引起的,但我不明白为什么。为什么不同于将 Object 关闭到一个方法和使用 try / catch p>

THE QUESTION

Why wouldn't my original attempt work? Why does the use of the intermediary, that has the identical structure, make it work? It seems caused by the difference in the throws clause but I don't see why. Why is it different than passing an Object off to a method and surrounding a call with a try/catch?

推荐答案

您最初尝试 wrapConsumer Consumer 作为参数,您尝试包装的lambda表达式仍然抛出异常 - 检查的异常。您的尝试 / catch 距离抛出的异常太远,因为在创建lambda表达式的时候, ve在 Consumer 上创建了 消费者接受方法 isn

Your initial attempt at wrapConsumer didn't work because it still took a Consumer as a parameter, and your lambda expression that you attempted to wrap still threw an Exception -- a checked exception. Your try/catch is too far from the thrown exception, because at the point you create a lambda expression, you've created a Consumer there, and Consumer's accept method isn't declared to throw any checked exceptions.

更改为接受 ConsumerWrapper ,因为该接口的方法声明允许它用 throws Exception 来抛出异常。这允许你创建一个lambda表达式,引发一个检查异常。

The change to accepting a ConsumerWrapper works because that interface's method declaration allows it to throw Exception, with throws Exception. That allows you to create a lambda expression that throws a checked exception.

这篇关于这些结构之间的区别是什么,一个不会编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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