我注意到,如果我编写类似以下内容的内容:

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似乎不同意。

最佳答案

请注意,这些选择都不完全相同。

View view = getView();
foo(error -> view.showError(error));

会立即评估getView(),但仅在实际评估函数时(但随后每次)才调用showError(error)。如果viewnull,则在评估函数时将抛出NullPoinerException
View view = getView();
foo(view::showError);

如果getView()NullPoinerException,它将立即评估view并立即抛出null。实际评估函数时,将调用showError(error);目前,请确保view不是null
foo(error -> getView().showError(error));

仅在实际评估函数时才评估getView();每次都会得出不同的结果。因此,如果NullPoinerException在此特定评估中返回getView(),则将在特定函数评估中抛出null

您的IDE建议将第一个变体转换为第二个变体,因为它在语义上是等效的,只要view不是null即可。相反,即使在非null情况下,第三种变体也存在显着差异,因为每次重新评估getView()可能会导致结果与早期绑定(bind)接收者实例不同。另请参阅“What is the equivalent lambda expression for System.out::println”。

当然,如果getView()是每次都返回相同实例的简单getter,则转换是合法的,但我想IDE不会考虑getView()的实现来做出这样的决定。由您决定此更改在​​您的应用程序中是否有效。

09-04 14:32
查看更多