5

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?

Talendar
  • 1,841
  • 14
  • 23
The Scientific Method
  • 2,374
  • 2
  • 14
  • 25
  • You mean a `class` that `implements` the SMI or `Student`? – Boris the Spider Oct 18 '18 at 12:10
  • http://www.lambdafaq.org/are-lambda-expressions-objects/ – Joe Clay Oct 18 '18 at 12:12
  • @BoristheSpider i mean a class the implements CheckStudent - it is a functional interface – The Scientific Method Oct 18 '18 at 12:13
  • Of course, it might be clearer if you can refactor `(Student s) -> s.getGender() == Student.Sex.MALE && s.getAge() >= 18 && s.getAge() <= 25` by introducing a local variable of class `CheckStudent` similar to `CheckStudent checkStudent = (Student s) -> s.getGender() == Student.Sex.MALE && s.getAge() >= 18 && s.getAge() <= 25;` – Smutje Oct 18 '18 at 12:18
  • This should answer your question https://download.java.net/java/early_access/jdk11/docs/api/java.base/java/lang/invoke/LambdaMetafactory.html – Boris the Spider Oct 18 '18 at 12:33

1 Answers1

2

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

Community
  • 1
  • 1
Talendar
  • 1,841
  • 14
  • 23