制作一个功能接口
@FunctionalInterface
public RulesFact {
Object getPropertyValue(String propertyName);
}
方法内部的lambda实例。
public RulesFact rulesFactImpl(Object o) {
return propertyName->PropertyAccessorFactory.forBeanPropertyAccess(o).getPropertyValue(propertyName);
}
这个方法和上面的方法有区别吗?在上面的例子中,每次执行lambda时都会调用PropertyAccessorFactory.forBeanPropertyAccess
方法吗?螺纹安全性有区别吗?
public RulesFact rulesFactImpl(Object o) {
BeanWrapper accessor = PropertyAccessorFactory.forBeanPropertyAccess(o);
return propertyName->accessor.getPropertyValue(propertyName);
}
关于上述反射实用程序的Javadocs:Package org.springframework.beans
调用RulesFact.getPropertyValue
时执行lambda表达式。
这意味着每次调用RulesFact.getPropertyValue
时,第一个版本都会调用PropertyAccessorFactory.forBeanPropertyAccess(o)
,如果访问器可以随时间变化,这是很好的。
第二个版本在调用rulesFactImpl
时调用PropertyAccessorFactory.forBeanPropertyAccess(o)
,并缓存该值,这对性能有利,但如果访问器可以随时间变化,则不好。
FYI:第二个版本可以使用方法参考编写:
public RulesFact rulesFactImpl(Object o) {
BeanWrapper accessor = PropertyAccessorFactory.forBeanPropertyAccess(o);
return accessor::getPropertyValue;
}
稍微有点,但可能不是以你关心的方式,假设这些API写得相当好。
public RulesFact rulesFactImpl(Object o) {
return propertyName->PropertyAccessorFactory.forBeanPropertyAccess(o).getPropertyValue(propertyName);
}
这会返回一个RulesFact
,当被调用时,它会调用forBeanPropertyAccess
,然后对其执行任何操作。如果您多次调用它,它每次都会调用forBeanPropertyAccess
。
public RulesFact rulesFactImpl(Object o) {
BeanWrapper accessor = PropertyAccessorFactory.forBeanPropertyAccess(o);
return propertyName->accessor.getPropertyValue(propertyName);
}
这会调用forBeanPropertyAccess
一次,并围绕其值进行闭包。您可以将这个闭包看作是一个实例变量。从某种意义上说,我们正在制作RulesFact
的一个子类,它有一个名为accessor
的实例变量,其值在构建时只计算一次。如果我们多次调用这个lambda,forBeanPropertyAccess
将永远不会再被调用;它只会多次使用原始值。
它或多或少是相同的,但在功能上并不相同。假设PropertyAccessorFactory.forBeanPropertyAccess(o)
抛出异常。
在第一种情况下,rulesFactImpl(...)
永远不会抛出。如果从未调用过RulesFact.getPropertyValue
,则不会有任何异常。
在第二种情况下,rulesFactImpl(...)
总是抛出。