Is a class being instantiated in a lambda expressi

2019-02-24 04:16发布

问题:

This question already has an answer here:

  • What is a Java 8 Lambda Expression Compiled to? [duplicate] 1 answer

I have the following method invocation, in which I am passing a lambda expression. Is a class being instantiated implicitly here?

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

Method signature:

printStudents(List<Student> roster, CheckStudent checkstudet)


interface CheckStudent {
    boolean test(Student s);
}

Edit

Some of you suggested me to refactor the code, but the same question arises.

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

Is a class (I am not referring to class Student ) being instantiated on the right side of the assignment?

回答1:

The value of a lambda expression is a reference to an instance of a class. So, in practical terms, yes, an instance of a class is being created. See what the docs say:

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.

However, there is more to that than we can "see". There are many optimizations running under the hood. Depending on certain factors, a previously created object can, for example, be used again. This means that a new object need not be allocated on every evaluation of a lambda expression. Let's take a look at the docs:

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).

As you might have noticed, this is a complex topic. For a deeper understanding, take a look at the The Java® Language Specification, chapter “15.27.4. Run-time Evaluation of Lambda Expressions”.