我有以下方法调用,其中传递了一个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
)?
答案 0 :(得分:1)
lambda表达式的值是对类实例的引用。因此,实际上,是的,正在创建一个类的实例。看看文档怎么说:
在运行时,对lambda表达式的求值类似于 在正常范围内评估类实例创建表达式 完成生成对对象的引用。
但是,除了我们可以“看到”之外,还有更多的东西。引擎盖下有许多优化。根据某些因素,例如可以再次使用先前创建的对象。这意味着不需要在lambda表达式的每次评估中分配新对象。让我们看一下文档:
lambda表达式的计算与执行 lambda身体。具有以下属性的类的新实例是 分配和初始化,或者类的现有实例 引用了以下属性。
[...]
这些规则旨在为实施的灵活性 Java编程语言,其中:
不需要在每次评估中分配新对象。
由不同的lambda表达式产生的对象不必属于不同的类(例如,如果主体相同)。
评估产生的每个对象不必属于同一类(例如,捕获的局部变量可能是内联的)。
如果“现有实例”可用,则无需在先前的lambda评估中创建(可能已经分配了该实例) 例如,在封闭类的初始化期间)。
您可能已经注意到,这是一个复杂的主题。为了更深入地了解,请阅读Java®语言规范的第“15.27.4. Run-time Evaluation of Lambda Expressions” 章。