为什么方法引用ctor“throws”? ......也扔? [英] Why does a method reference to ctor that "throws" ... throw as well?

查看:114
本文介绍了为什么方法引用ctor“throws”? ......也扔?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种优雅的方式来创建依赖注入工厂。在我的例子中,工厂只需调用一个参数构造函数。我发现这个答案概述了如何使用功能< ParamType,ClassToNew> 出于这样的目的。

I am looking for an elegant way to create a factory for dependency injection. In my case, the factory simply has to call a one-argument constructor. I found this answer outlining how to use a Function<ParamType, ClassToNew> for such purposes.

但我的问题是:在我的情况下,我的ctor宣布抛出一些已检查的异常。

But my problem is: in my case, my ctor declares to throw some checked exception.

我没有得到:使用对该构造函数的方法引用创建 Function 不起作用。如:

What I don't get: creating that Function using a method reference to that constructor doesn't work. As in:

import java.util.function.Function;

public class Mcve {        
    public Mcve(String s) throws Exception {
        // whatever
    }        
    public static void main(String[] args) {
        Function<String, Mcve> mcveFactory = Mcve::new;
    }
}

告诉我未处理的异常:java.lang。 Mcve :: new 的例外情况。虽然此代码调用构造函数。

tells me about "Unhandled exception: java.lang.Exception" for Mcve::new. Although this code is not invoking the constructor.

两个问题:


  • 为什么会出现这个错误?上面的代码调用ctor(还)?

  • 有没有优雅的方法来解决这个难题? (只需添加抛出异常到我的 main() 帮助)

  • why that error? The above code does not invoke the ctor (yet)?
  • are there any elegant ways to solve this puzzle? ( simply adding throws Exception to my main() does not help )

推荐答案

您需要提供自定义界面 ThrowingFunction 它有一个方法抛出异常

You need to provide a custom interface ThrowingFunction which has one method that throws Exception.

public interface ThrowingFunction<ParameterType, ReturnType> {
    ReturnType invoke(ParameterType p) throws Exception;
}

public class Mcve {
    public Mcve(String s) throws Exception {
        // whatever
    }
    public static void main(String[] args) {
        ThrowingFunction<String, Mcve> mcveFactory = Mcve::new;
    }
}

使用此方法会导致调用 mcveFactory.invoke(lalala); 强制您处理构造函数抛出的异常。

Using this approach results in calling mcveFactory.invoke("lalala"); forcing you to handle the exception thrown by the constructor.

错误原因是您要存储的实际函数引用(不是100%确定术语)会引发异常,因此类型根本不匹配。 如果你可以在一个函数中存储 Mcve :: new ,那么调用该函数的人不再知道一个<$ c可以抛出$ c>异常。如果实际抛出异常会怎么样?抛出异常并丢弃它都不起作用。

Reason for the error is that the actual function reference you want to store (not 100% sure about the terminology) throws an exception and therefore the types simply do not match up. If you could store Mcve::new inside a function then whoever calls the function no longer knows an Exception can be thrown. What would then happen if the exception would actually be thrown? Both throwing the exception and discarding it do not work.

备选:如果你需要实际检索函数< String,Mcve> 最后你需要编写一个调用构造函数的函数(或lambda),捕获异常并将其丢弃或重新抛出包装在未经检查的<$中c $ c> RuntimeException 。

Alternative: if you need to actually retrieve a Function<String, Mcve> in the end then you need to write a function (or lambda) that invokes the constructor, catches the exception and either discards it or rethrows it wrapped inside a unchecked RuntimeException.

public class Mcve {
    public Mcve(String s) throws Exception {
        // whatever
    }

    public static void main(String[] args) {
        Function<String, Mcve> mcveFactory = parameter -> {
            try {
                return new Mcve(parameter);
            } catch (Exception e) {
                throw new RuntimeException(e); // or ignore
            }
        };
    }
}






我认为错误消息本身至少有点误导,因为你通常在实际调用方法时会看到它。我当然可以理解导致第一个子问题的混乱。更清楚(遗憾的是不可能)陈述类似


I would argue that the error message itself is at least a bit misleading since you normally see it when actually invoking the method. I can certainly understand the confusion resulting in the first sub-question. It would be clearer (sadly not possible) to state something like


不兼容的类型功能< String,Mcve> 功能< String,Mcve>抛出异常

这篇关于为什么方法引用ctor“throws”? ......也扔?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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