当前位置: 首页 > 面试题库 >

为什么我们不能在lambda表达式中使用默认方法?

扶开诚
2023-03-14
问题内容

我正在阅读有关Java
8的教程,作者在
其中显示了代码:

interface Formula {
    double calculate(int a);

    default double sqrt(int a) {
        return Math.sqrt(a);
    }
}

然后说

无法从lambda表达式内访问默认方法。以下代码无法编译:

Formula formula = (a) -> sqrt( a * 100);

但是他没有解释为什么这是不可能的。我运行了代码,但出现了错误,

不兼容的类型:公式不是功能界面`

那么为什么不可能或错误的含义是什么呢? 该接口满足具有一种抽象方法的功能接口的要求。


问题答案:

这或多或少是范围的问题。从JLS

与出现在匿名类声明中的代码不同,在lambda正文中出现的名称和thisand
super关键字的含义以及引用声明的可访问性与周围上下文相同(除了lambda参数引入新名称)。

在您尝试的示例中

Formula formula = (a) -> sqrt( a * 100);

范围不包含名称声明sqrt

JLS也暗示了这一点

实际上,lambda表达式需要谈论自己 (以递归方式调用其自身或调用其其他方法) 是不寻常的
,而使用名称来引用封闭类中的东西则更为常见。否则会被阴影(thistoString())遮盖。
如果有必要让lambda表达式引用自身(如viathis),则应改用方法引用或匿名内部类。

我认为它可能已经实施。他们选择不允许。



 类似资料:
  • 我知道使用lambda expression(LE)我们可以节省一些代码行,比如为函数接口创建对象。而且LE将更易读。但我确信这并不是提供该功能的主要原因。我在google上搜索,并在本文中找到了这段有趣的引用 在Java8之前,处理任何集合的元素都可以通过从集合中获取迭代器,然后迭代元素,然后处理每个元素来完成。如果需要并行处理这些元素,那么将由客户端代码完成。随着Java 8中Stream A

  • 我正在尝试理解语法。考虑以下程序: 在上面的程序中,模式匹配中使用的编译正常。当我尝试在like我得到编译错误: 我试图理解为什么不能在中使用。

  • 问题内容: 我升级到Java 8,并尝试用新的lamdba表达式替换Map中的简单迭代。循环搜索空值,如果找到一个,则引发异常。旧的Java 7代码如下所示: 我将其转换为Java 8的尝试如下所示: 谁能解释为什么此处不允许该声明以及如何更正该声明? Eclipse的快速修复建议对我来说并不正确……它只是在语句周围加上了一个块: 问题答案: 不允许抛出检查异常,因为接口中的方法未在其子句中声明任

  • 我升级到Java 8,并试图用一个新的lamdba表达式替换通过映射的简单迭代。循环搜索空值,如果找到,则抛出异常。旧的Java 7代码如下所示: 我尝试将其转换为Java 8,如下所示: 有人能解释为什么这里不允许语句以及如何纠正这一点吗? Eclipse的快速修复建议在我看来不太对劲......它只是用块包围语句:

  • 我试图表达10的幂10,但它不起作用,所以我认为问题是数据类型的范围。 我的预期答案是10000000000,但运算结果是1410065408 有什么问题?

  • Lambda表达式必须转换为函数接口。据我所知,他们不能扩展一个类,但我想知道是否有办法得到类似的东西。 我有