变量与对象返回的对象的方法引用

时间:2017-12-14 14:15:22

标签: java android-studio intellij-idea lambda method-reference

我注意到如果我写的东西:

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

2 个答案:

答案 0 :(得分:3)

请注意,这些替代方案都不完全等效。

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

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

getView()
如果NullPoinerExceptionview

会立即评估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会给出直接使用方法引用的建议。如果您不打算再次使用它,则保存对象引用没有意义。希望它有所帮助。