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

时间:2018-10-18 12:08:31

标签: java lambda functional-interface

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

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;

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

1 个答案:

答案 0 :(得分:1)

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

  

在运行时,对lambda表达式的求值类似于   在正常范围内评估类实例创建表达式   完成生成对对象的引用。

但是,除了我们可以“看到”之外,还有更多的东西。引擎盖下有许多优化。根据某些因素,例如可以再次使用先前创建的对象。这意味着不需要在lambda表达式的每次评估中分配新对象。让我们看一下文档:

  

lambda表达式的计算与执行   lambda身体。具有以下属性的类的新实例是   分配和初始化,或者类的现有实例   引用了以下属性。

     

[...]

     

这些规则旨在为实施的灵活性   Java编程语言,其中:

     
      
  • 不需要在每次评估中分配新对象。

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

  •   
  • 评估产生的每个对象不必属于同一类(例如,捕获的局部变量可能是内联的)。

  •   
  • 如果“现有实例”可用,则无需在先前的lambda评估中创建(可能已经分配了该实例)   例如,在封闭类的初始化期间)。

  •   

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