【问题标题】:Java 8 [cannot infer type variables] problemJava 8 [无法推断类型变量] 问题
【发布时间】:2019-03-20 18:06:25
【问题描述】:

我有一个 ThrowingFunction<T, R, E extends Exception> 功能接口,其中包含一个具有此签名的抽象方法:R apply(T t) throws E

我在功能界面中有一个静态实用程序方法,允许用户将ThrowingFunction<T, R, E extends Exception> 实例转换为Function<T, R> 实例:

static <T, R> Function<T, R> unchecked (final ThrowingFunction<T, R, ?> tf)
{
    // code here
}

这里的问题是,如果我将方法引用URL::new 传递给unchecked 静态实用程序方法,为什么编译器不会推断出类型参数TR

final URL url = unchecked(URL::new).apply("http://www.examples.com");

我的意思是,URL::new 不是ThrowingFunction&lt;String, URL, MalformedURLException&gt; 的有效候选,因此TR 应该分别被推断为StringURL

【问题讨论】:

    标签: generics lambda java-8 type-inference method-reference


    【解决方案1】:

    您是对的,它应该可以工作,这很可能与您使用方法引用并且编译器不知何故感到困惑的事实有关,有两种解决方案:

    // a lambda
    ThrowingFunction.unchecked((String x) -> new URL(x));
    
    
    // an explicit cast
    ThrowingFunction.unchecked((ThrowingFunction<String, URL, MalformedURLException>)URL::new);
    

    【讨论】:

    • 两个答案对我来说都很好,我选择了 lambda 方法,因为它在显式类型参数馈送方面不太明确。
    • 问题是URL有多个构造函数。您希望编译器根据预期的函数类型选择构造函数,而它需要知道实际的目标构造函数来确定函数类型。原则上,考虑到数量已经足以确定正确的组合,但当前的 Java 语言并没有这样做。因此,相比之下,URL url = unchecked(URI::create) .andThen(unchecked(URI::toURL)) .apply("http://www.examples.com"); 将起作用,因为只有一个 URI::create 方法……
    • @Holger 当您认为我实际上已经回答了一些关于此的问题时.. :|谢谢
    【解决方案2】:

    我不知道问题是什么,但答案是yes,它是一个有效的候选人,如果你把它分成两个陈述,它就可以工作:

    ThrowingFunction<String, URL, MalformedURLException> ctor = URL::new;
    final URL url = unchecked(ctor).apply("http://www.examples.com");
    

    【讨论】:

    • 如果拆分,所有类型都是已知的并且是显式的,这与方法引用无法推断类型有关
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-21
    • 2017-08-05
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多