是否在lambda表达式中实例化了一个类?

The*_*hod 5 java lambda functional-interface

我有以下方法调用,其中传递了一个lambda表达式。这里是否隐式实例化了一个类?

printStudents(
    roster,
    (Student s) -> s.getGender() == Student.Sex.MALE
        && s.getAge() >= 18
        && s.getAge() <= 25
);
Run Code Online (Sandbox Code Playgroud)

方法签名:

printStudents(List<Student> roster, CheckStudent checkstudet)
Run Code Online (Sandbox Code Playgroud)


interface CheckStudent {
    boolean test(Student s);
}
Run Code Online (Sandbox Code Playgroud)

编辑

你们中有些人建议我重构代码,但是出现了同样的问题。

CheckStudent checkStudent = (Student s) -> s.getGender() == Student.Sex.MALE && s.getAge() >= 18 && s.getAge() <= 25;
Run Code Online (Sandbox Code Playgroud)

是否Student在作业的右侧实例化了一个类(我不是指class )?

Tal*_*dar 2

lambda 表达式的值是对类实例的引用。所以,实际上,是的,正在创建一个类的实例。看看文档怎么说:

\n
\n

在运行时,lambda 表达式的求值类似于类实例创建表达式的求值,只要正常完成会生成对对象的引用。

\n
\n

然而,事情远比我们“看到”的要多。有许多优化在幕后运行。例如,根据某些因素,可以再次使用先前创建的对象。这意味着不需要在每次计算 lambda 表达式时都分配一个新对象。让我们看一下文档:

\n
\n

lambda 表达式的求值与 lambda 主体的执行不同。分配并初始化具有以下属性的类的新实例,\n或者引用具有以下属性的类的现有实例。

\n

[...]

\n

这些规则旨在为 Java 编程语言的实现提供灵活性,因为:

\n
    \n
  • 不需要在每次评估时分配新对象。

    \n
  • \n
  • 由不同 lambda 表达式生成的对象不必属于不同的类(例如,如果主体相同)。

    \n
  • \n
  • 通过评估生成的每个对象不需要属于同一类(例如,捕获的局部变量可能是内联的)。

    \n
  • \n
  • 如果“现有实例”可用,则无需在先前的 lambda 求值中创建它(例如,它可能已在封闭类的初始化期间分配)。

    \n
  • \n
\n
\n

您可能已经注意到,这是一个复杂的主题。要更深入地了解,请查看Java\xc2\xae 语言规范,章节\xe2\x80\x9c15.27.4。Lambda 表达式\xe2\x80\x9d 的运行时评估

\n