我注意到如果我写的东西:
View view = getView();
foo(error -> view.showError(error));
Android Studio(也可能是IntelliJ)显示“可以用方法参考替换”的建议。
相反,如果我写
foo(error -> getView().showError(error));
Android Studio没有说什么。
但在这两种情况下我都可以使用方法引用:
foo(view::showError)
和
foo(getView()::showError)
,分别。
这两种形式在功能上有何不同?他们似乎在做同样的事情,但Android Studio似乎不同意。
答案 0 :(得分:3)
请注意,这些替代方案都不完全等效。
View view = getView();
foo(error -> view.showError(error));
会立即评估getView()
,但仅在实际评估函数时调用showError(error)
(但每次都会调用view
)。如果null
为NullPoinerException
,则在评估函数时将抛出View view = getView();
foo(view::showError);
。
getView()
如果NullPoinerException
为view
,会立即评估null
并立即抛出showError(error)
。实际评估函数时将调用view
;目前,保证null
不是foo(error -> getView().showError(error));
。
getView()
只有在实际评估函数时,才会评估NullPoinerException
;它可以每次评估到不同的结果。因此,如果getView()
在此特定评估中返回null
,则会在特定功能评估中抛出view
。
您的IDE建议将第一个变体转换为第二个变体,因为它在语义上是等效的,只要null
不是null
即可。相比之下,即使在非getView()
情况下,第三个变体也有显着差异,因为每次重新评估getView()
可能导致与早期绑定接收器实例不同的结果。另请参阅“What is the equivalent lambda expression for System.out::println”。
当然,如果getView()
是一个微不足道的getter,每次都会返回相同的实例,那么转换将是合法的,但我认为IDE没有考虑{{1}}的实现做出这样的决定。您可以自行决定此更改是否在您的应用程序中有效。
答案 1 :(得分:0)
两者完全相同,但如果你不多次使用一个对象,那么android studio会给出直接使用方法引用的建议。如果您不打算再次使用它,则保存对象引用没有意义。希望它有所帮助。