假设我有如下代码:
class Foo {
Y func(X x) {...}
void doSomethingWithAFunc(Function<X,Y> f){...}
void hotFunction(){
doSomethingWithAFunc(this::func);
}
}
假设hotFunction
经常被调用。那么缓存this::func
是否可取,可能如下所示:
class Foo {
Function<X,Y> f = this::func;
...
void hotFunction(){
doSomethingWithAFunc(f);
}
}
就我对java方法引用的理解而言,当使用方法引用时,虚拟机会创建一个匿名类的对象。因此,缓存引用将只创建该对象一次,而第一种方法在每次函数调用时创建该对象。这是正确的吗?
是否应该缓存出现在代码中热门位置的方法引用,或者VM是否能够优化这一点并使缓存变得多余?有没有关于这方面的一般最佳实践,或者这种高度的VM实现是否特定于这种缓存是否有用?
发布于 2015-09-29 05:38:24
不幸的是,如果将lambda作为您希望在将来某个时候删除的侦听器进行传递,则这是一种很好的理想情况。在传递另一个this::方法引用时,需要缓存的引用在删除过程中不会被视为相同的对象,原始引用也不会被删除。例如:
public class Example
{
public void main( String[] args )
{
new SingleChangeListenerFail().listenForASingleChange();
SingleChangeListenerFail.observableValue.set( "Here be a change." );
SingleChangeListenerFail.observableValue.set( "Here be another change that you probably don't want." );
new SingleChangeListenerCorrect().listenForASingleChange();
SingleChangeListenerCorrect.observableValue.set( "Here be a change." );
SingleChangeListenerCorrect.observableValue.set( "Here be another change but you'll never know." );
}
static class SingleChangeListenerFail
{
static SimpleStringProperty observableValue = new SimpleStringProperty();
public void listenForASingleChange()
{
observableValue.addListener(this::changed);
}
private<T> void changed( ObservableValue<? extends T> observable, T oldValue, T newValue )
{
System.out.println( "New Value: " + newValue );
observableValue.removeListener(this::changed);
}
}
static class SingleChangeListenerCorrect
{
static SimpleStringProperty observableValue = new SimpleStringProperty();
ChangeListener<String> lambdaRef = this::changed;
public void listenForASingleChange()
{
observableValue.addListener(lambdaRef);
}
private<T> void changed( ObservableValue<? extends T> observable, T oldValue, T newValue )
{
System.out.println( "New Value: " + newValue );
observableValue.removeListener(lambdaRef);
}
}
}
在这种情况下,如果不需要lambdaRef就好了。
https://stackoverflow.com/questions/23983832
复制相似问题