class 是否在 lambda 表达式中被实例化?

Is a class being instantiated in a lambda expression?

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

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

方法签名:

printStudents(List<Student> roster, CheckStudent checkstudet)


interface CheckStudent {
    boolean test(Student s);
}

编辑

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

CheckStudent checkStudent = (Student s) -> s.getGender() == Student.Sex.MALE && s.getAge() >= 18 && s.getAge() <= 25;

一个class(我指的不是class Student)是在赋值的右边被实例化了吗?

lambda 表达式的值是对 class 实例的引用。因此,实际上,是的,正在创建 class 的实例。查看文档怎么说:

At run time, evaluation of a lambda expression is similar to evaluation of a class instance creation expression, insofar as normal completion produces a reference to an object.

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

Evaluation of a lambda expression is distinct from execution of the lambda body. Either a new instance of a class with the properties below is allocated and initialized, or an existing instance of a class with the properties below is referenced.

[...]

These rules are meant to offer flexibility to implementations of the Java programming language, in that:

  • A new object need not be allocated on every evaluation.

  • Objects produced by different lambda expressions need not belong to different classes (if the bodies are identical, for example).

  • Every object produced by evaluation need not belong to the same class (captured local variables might be inlined, for example).

  • If an "existing instance" is available, it need not have been created at a previous lambda evaluation (it might have been allocated during the enclosing class's initialization, for example).

您可能已经注意到,这是一个复杂的话题。要更深入地了解,请查看 Java® 语言规范,第 “15.27.4. Run-time Evaluation of Lambda Expressions” 章。