当前位置: 首页 > 知识库问答 >
问题:

为什么类型推断对于lambda失败,对于等效方法引用却成功?

东方国安
2023-03-14
public class Main
{
    public static void main(String... args)
    {
        methodB(thing -> Main.testRound(thing)); // incompatible types
        methodB(Main::testRound);                // no problem here
    }

    static <T extends Shape> void methodB(Func<T> function)
    {
    }

    static boolean testRound(Round thing)
    {
        return true;
    }
}

interface Func<T>
{
    boolean test(T ob);
}

class Shape
{
}

class Round extends Shape
{
}

Vince Emigh找到了答案,我在下面标记为“接受”。虽然这不是我的问题的一部分,但这里有四种方法可以解决这样一个问题,即lambda只有在真正坚持使用lambda时才会被推断为func 类型:

// Use a type witness.

Main.<Round>methodB(thing -> testRound(thing));

// Make the lambda's argument type explicit.

methodB((Round thing) -> testRound(thing));

// Cast the argument.

methodB(thing -> testRound((Round)thing));

// Store the lambda reference in a Func<Round> variable.

Func<Round> lambda = thing -> testRound(thing);
methodB(lambda);

我看不出有什么理由更喜欢其中一个而不是方法引用,除非你觉得lambdas的密密麻麻程度低一点(也许可读性高一点)。但是,如果你想要的话,他们就在那里。

共有1个答案

郭弘盛
2023-03-14

根据JLS第15.13.2节:

与lambda表达式不同,方法引用可以与泛型函数类型(即具有类型参数的函数类型)全等。这是因为lambda表达式需要能够声明类型参数,而没有语法支持这一点;而对于方法引用,则不需要这样的声明。

lambda表达式引发错误,因为没有指定类型参数。这会导致t被编译为shape(正如您的文章中提到的),因为没有任何东西可以帮助推断参数的类型。

 类似资料:
  • 问题内容: 我有一个奇怪的场景,在使用lambda表达式时,类型推断无法按预期工作。这是我实际情况的近似值: 我倒数第二行的编译错误是 未为对象类型定义方法booleanValue() 如果我将lambda转换为: 或者如果我将方法签名更改为使用原始类型: 然后问题就解决了。我希望它能起作用的方式是: 调用应推断返回类型为 在lambda中应该推断为。 为什么这种推论不能按预期方式工作?如何更改此

  • 我在Haskell编程中的冒险并不都是史诗般的。我正在实现简单的Lambda演算,我很高兴完成了、以及,希望它们是正确的。剩下的是,就像红色框中定义的那样(在下图中),我正在为此寻找指导。 如果我说错了请指正, (1)但是我发现返回给定变量的类型。Haskell中的什么构造返回?我知道在中是,但我正在寻找一个在下工作的。 (3)对于(T-APP)和(T-ABS),我假设我分别对和应用程序应用了替换

  • 问题内容: 为什么我的代码不起作用? 结果是:0 1 2 3 4 5 6 7 8 9。 我期待一个 随机改组的序列 。 问题答案: 不能按预期应用于原始类型的数组。当应用于时,将产生的列表,而不是的列表。因此,您将重新整理一个新创建的列表。 这是Java中可变参数和泛型的微妙行为。被声明为 因此,它可以采用某些类型的多个参数并生成包含这些参数的列表,也可以采用一个类型的参数并返回此数组支持的列表(

  • 我有一个奇怪的场景,当使用lambda表达式时,类型推断没有像我预期的那样工作。以下是我真实场景的近似值: 我在倒数第二行得到的编译错误是 方法booleanValue()未为类型Object定义 如果我将lambda转换为

  • 以下片段使用Clang 4.0编译没有错误,但GCC 7.0会产生错误(注意使用-std=c 1z标志)。 具体来说,GCC抱怨lambda和嵌套类的方法都没有链接,因此它们不能用作非类型模板参数。 至少对于lambda的情况,我认为Clang是正确的(而GCC是错误的),因为(引用转换操作符cppreference): 此转换函数返回的值是指向具有C语言链接的函数的指针,调用该函数时,其效果与直

  • 我正在尝试编写一个android静态编程语言应用程序,但我得到了以下错误。我哪里出错了? 这是我如何声明我的HashMap: 错误: 类型推断失败。没有足够的信息来推断构造函数HashMap中的参数K。请明确说明